Flask - Cookie and Token Sessions Simultaneously
However, sometimes you may want (or need) to colour outside the lines, where a cookie-cutter implentation either doesn’t work, or gets in the way.
One such scenario is if you have an application which needs to act both as a web front-end, with your typical cookie-based sessions, as well as an API endpoint. Requiring cookies when you’re acting as an API endpoint isn’t particularly nice, tokens in the request header is the way to go! So how can you get Flask sessions to work with both these methods of identification?
Perhaps at this point, I should add that you might be best served by reconsidering your strategy here, and make the API endpoint a distinct application from the one driving your UI. You can still share all your code for your models and logic and can even make use of a layer 7 load balancer to deal with the separation for you. But be it due to retrofitting, time constraint, legacy or otherwise imposed design.. here goes;
Since Flask is a pretty lightweight framework, it’s easily extended or wrestled into submission. Luckily for us, it offers a pluggable way to write your own session handling!
I’ve put a small example application with a custom session interface on
allows what we’ve previously discussed. You can either distinguish sessions by
a cookie, if present, or a header of your chosing (cookie trumps header, if
both are present). This header defaults to the
X-Auth-Header in the example, but you can configure this
For ease of use, the datastore used to store the sessions is memcached. But
it’s very easily replaced by any other datastore.
The example is as small and compact as possible while remaining runnable. There are no “bells and whistles” such as actual authentication, that’s for you to handle outside of the session handler. You will also most likely want to extend the error checking and handling.
Do note - there’s a docker-compose file
included in the repository, which will enable you to quickly get up and
Alternatively you can simply run
pip install -r requirements.txt && ./runserver.py from
app/ directory, provided that you have the required system
Here’s an example of using this session handler with cookies:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Since we don’t send a JSON body containing the key
token, or set the
X-Auth-Token header, the session handler determines the application should send a cookie.
The example has a session timeout of a mighty 30 seconds (configurable, obviously).
Now, if we were to behave like an API, on the other hand:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
As you can see, we don’t get a cookie sent back, because we behaved like an API client. We can also see that we get a brand new session after the 30 seconds has elapsed.
The example also comes with a test suite for verification. You can execute this
by simply running
1 2 3 4 5 6 7 8 9 10 11 12 13
The tests all run in a docker container, so the first time you run it, you’ll most likely see an image being built, and a memcached image being pulled.
Hope this helps someone!