Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually validate flask-extended-jwt's access token

I have a SPA app that contains an form with an upload file field. I have a rest API whose endpoints are protected via flask-extended-jwt JWT. To authenticate the REST endpoints I use @jwt_required. I want to authenticate the upload request as well.

Because of the client side I can't add an Authorization Bearer header so I thought to add the access token as a hidden field when submitting the form.

What is the best way to manually validate the JWT access token after I read it from the form?

class Upload(Resource):

def post(self):
    #TODO: check for access token
    access_token = None
    if 'access_token' in request.form and request.form['access_token']:
        access_token = request.form['access_token']
    else:
        message = json.dumps({'message': 'Invalid or missing token', 'success': False})
        return Response(response=message, status=401, mimetype='text/plain')

    if access_token:
        #TODO: validate_token(access_token)

Thank you

like image 850
florin Avatar asked Aug 20 '18 14:08

florin


1 Answers

Author of flask-jwt-extended here. That's a great question. There is currently no supported way to do that in the extension, the grabbing the token from the request and decoding it are tightly coupled together. This would be hard to de-couple because there is a lot of conditional things that are going on when the full decode chain runs. For example, checking the CSRF value only if the request is sent in via a cookie, or differentiating between an access and refresh token for the sake of the blacklisting feature.

A generalized function could be created, it's signature would look something like decode_and_verify_jwt(encoded_token, is_access_token=True, check_csrf=False). However, this would complicate the rest of the code in flask_jwt_extended and be a rather confusing function to use for the general case.

I think in this case it would be easier just to add a fourth lookup in the extension, so you could use something like:

app.config['JWT_TOKEN_LOCATION'] = ['headers', 'forms']
app.config['JWT_FORM_KEY'] = 'access_token'
# Use the rest of the application normally

If you want to make a ticket on the github page so I can track this, I would be happy to work on it.

like image 194
vimalloc Avatar answered Oct 20 '22 12:10

vimalloc