Token based authentication with flask-security extension Token based authentication with flask-security extension flask flask

Token based authentication with flask-security extension


Endpoint is /login, you post your credentials as json request body:

{'email':'john@smit.com', 'password':'1234'}

However for this to work you need to disable the csrf tokens in your flask app (thanks Mandar Vaze):

app.config['WTF_CSRF_ENABLED'] = False

Then you do each request with the token in the HTTP headers:

Authentication-Token:WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0

Or as query string:

http://localhost:5000/protected?auth_token=WyI1NTE1MjhmNDMxY2Q3NTEwOTQxY2ZhYTgiLCI2Yjc4NTA4MzBlYzM0Y2NhZTdjZjIxNzlmZjhiNTA5ZSJd.B_bF8g.t1oUMxHr_fQfRUAF4aLpn2zjja0

Client example in python 3:

import requestsimport json#do the loginr = requests.post('http://localhost:5000/login',                     data=json.dumps({'email':'john@smit.com', 'password':'1234'}),                     headers={'content-type': 'application/json'})response = r.json()print(response) #check responsetoken = response['response']['user']['authentication_token']    #set token value#Now you can do authorised callsr = requests.get('http://localhost:5000/protected',                 headers={'Authentication-Token': token})print(r.text)

Angular example snippet to obtain the token:

$http.post('/login', {"email": $scope.formdata.login,"password":$scope.formdata.password}).            success(function(results) {            $window.sessionStorage.token = results.response.user.authentication_token;            });

Angular example snippet to visit protected pages:

 if ($window.sessionStorage.getItem('token')) {                config.headers['Authentication-Token'] = $window.sessionStorage.getItem('token');            }


I found Flask-Security's token-based not a good candidate for my project. I recommend using JWT token instead.

The problems with Flask-Security's token based authentication.

  1. Need to disable CSRF globally, this is not good when you also have a traditional web application in which CSRF token is desirable
  2. No easy way to renew the token ( without submitting password again )
  3. Can not control the payload of the token, there's no API to put/get data to/from the token
  4. That token, by design, only works with one Flask app. So if your frontend app needs to talk with multiple restful apis, this wont work well

Check out JWT (pyjwt or flask-jwt) token, it solves all the above problems and more.


Authentication endpoint is /login

Look at the code of flask-security here specifically views.py: _render_json()

login() calls _render_json which in turn calls get_auth_token() - and returns the auth token.

Problem (for me) is to get this to work.For me request.json seems empty (hence this does not work)

{"email": "test@example.com", "password": "test123"}

Hopefully this helps you move forward a little.