FastAPI – Unable to get auth token from middleware's Request object

Question:

Following Starlette documentation (FastAPI uses Starlette for middlewares), response.headers["Authorization"] should allow me to get the bearer token, but I get a KeyError saying no such attribute exists.

When I print response.headers, I get MutableHeaders({'content-length': '14', 'content-type': 'application/json'}).

Why is the authorization attribute not in the header despite of making a request with an auth header?

@app.middleware("http")
async def validate_access_token(request: Request, call_next):
    response = await call_next(request)
    access_token = response.headers["Authorization"].split()
    is_valid_signature = jwt.decode(access_token[1], key=SECRET, algorithms=CRYPT_ALGO)
    
    if is_valid_signature:
        return response
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, 
            detail='Invalid access token'
        )
Asked By: Jpark9061

||

Answers:

You are trying to retrieve the Authorization header from the Respone instead of the Request object (as you mentioned in the title of your question). Hence, you should instead use:

access_token = request.headers['Authorization']
               ^^^^^^^

or

access_token = request.headers.get('Authorization')

Additionally, instead of a middleware, it might be better to use Dependencies, along with FastAPI’s OAuth2PasswordBearer (you can find the implementation here), similar to this answer (which demonstrates how to achieve authentication using the third-party package FastAPI_Login – have a look at the relevant implementation here).

Answered By: Chris