pythonjwtflask-jwt-extendedflask-jwt

Missing Authorization Header in production only


I have the following work flow:

I have a api/token [POST] that takes form-data (email and password) and returns and access token and a refresh token.

Then I have another endpoint api/users/info [GET] (with Headers 'Authorization': 'Bearer ...) that returns user information. When testing locally both endpoints work.

When testing to my deployed server only the token fetching one works.

Here is the code for the api/users/info:

@API_BP.route('/users/info', methods=['GET'])
@fresh_jwt_required
def users_info():

    user_identity = get_jwt_identity()
    curr_user = (SDB.session.query(User)
                 .filter_by(email=user_identity).one_or_none())
    return jsonify({
        'greeting': 'Hello, World!',
        'foo': 'bar',

    })

Moreover, here are my configs:

JWT_TOKEN_LOCATION = ['cookies', 'headers']
JWT_COOKIE_CSRF_PROTECT = True
JWT_COOKIE_SECURE = True 
JWT_ACCESS_COOKIE_NAME = "my_access_cookie"
JWT_REFRESH_COOKIE_NAME = "my_refresh_cookie"
JWT_ACCESS_CSRF_COOKIE_NAME = "my_csrf_access_token"
JWT_REFRESH_CSRF_COOKIE_NAME = "my_csrf_refresh_token"
JWT_ACCESS_CSRF_HEADER_NAME = "X-MY-TOKEN"

The error I am getting is:

{
    "msg": "Missing JWT in cookies or headers (Missing cookie \"my_access_cookie\"; Missing Authorization Header)"
}

I'm using Postman to hit these endpoints. I have the Token received by api/token set under authorization. Here is what that looks like in python:

import requests

url = "http://my_url.com/api/users/info"

payload = {}
headers = {
  'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhrtyuzI1NiJ9.eyJpYXQiOjE2MjU5MTg0MTEsIm5iZiI6MTYyNTkxODQxMSwianRpfghZi00YTcyLWIxZTYtZGMxYTRjNDhkOThhIiwiZXhwIjoxNjI1OTE5NjExLCJpZGVudGl0eSI6ImFsZnJlZG9Adml2ZWJlbmVmaXRzLmNvbSIsImZyZXNoIjp0cnVlLCsdfghXBlIjoiYWNjZXNzIiwiY3NyZiI6ImQyNTQ0NjY0LTFlOGUtNDY5NS1hY2I4LTE2MzIxMDZlNDY0MiJ9.WT-EWlMtZZKoNyiXYxa3xdfghjg7r7ys'
}

response = requests.request("GET", url, headers=headers, data = payload)

print(response.text.encode('utf8'))

What can I do to ensure the second request GET works in prod?


Solution

  • The issue is that verify_jwt_in_request() would look for the header Authorization instead of X-Forwarded-Authorization.

    Locally, the header would be Authorization but in production, because we are using docker/nginx, the header changes to X-Forwarded-Authorization. The way I fixed this was to set the config JWT_HEADER_NAME = "X-Forwarded-Authorization"