0

Background:

I'm trying to prototype a quick token-based authentication using Flask-Restful and PyJWT. The idea is that I will have a form with email and password and when user clicks submit, it will generate a token and save it in client side browser and use it in any subsequent requests until the token expires.

Trouble

In my prototype, I was able to create a token using JWT but I don't have an idea of how to pass the JWT into a subsequent request. When I do it in the Postman, it works because I can specify the Authorization header with token in there. But when I login in through UI and token is generated, I do not know how to pass the token generated into a subsequent request (/protected) by making the token persists in the header until it expires. Currently when I login from UI and go to /protected, the Authorization header is missing in /protected header.

Code

class LoginAPI(Resource):
    # added as /login

    def get(self):
        """
        renders a simple HTML with email and password in a form.
        """
        headers = {'Content-Type': 'text/html'}
        return make_response(render_template('login.html'), 200, headers)

    def post(self):

        email = request.form.get('email')
        password = request.form.get('password')

        # assuming the validation has passed.

        payload = {
            'user_id': query_user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
        }

        token = jwt\
            .encode(payload, current_app.config['JWT_SECRET'], current_app.config['JWT_ALGORITHM'])\
            .decode('utf-8')

        # Is below the right way to set the token into header to be used in subsequent request?
        # request.headers.authorization = token

        # when {'authorization': token} below as a header, the header only shows up for /login not for any subsequent request.

        return make_response({'result': 'success', 'token': token}, 200, {'authorization': token} )


class ProtectedAPI(Resource):
    @check_auth
    def get(self):

        return jsonify({'result': 'success', 'message': 'this is a protected view.'})


# decorator to check auth and give access to /protected
def check_auth(f):

    @wraps(f)
    def authentication(*args, **kws):
        # always get a None here.
        jwt_token = request.headers.get('authorization', None)
        payload = jwt.decode(jwt_token, 'secret_key', algorithms='HS512'])
        # other validation below skipped.
    return f(*args, **kws)
return authentication
Jessi
  • 1,378
  • 6
  • 17
  • 37
  • How is your frontend (UI) built? How do you do your requests? The issue comes from there. Generally, people store the token in their UI and put it in the header when they do requests. – Michael Sep 27 '19 at 15:48

1 Answers1

0

To persist the access_token you have to store on the client and pass it into your header every time you call your backend and check the authenticity of the token every time.

Tekill
  • 1,171
  • 1
  • 14
  • 30