FastAPI - Unable to get auth token from middleware's Request object
Asked Answered
L

1

1

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'
        )
Langille answered 26/12, 2022 at 6:49 Comment(5)
And where did you expect the header to come from? Did you set it yourself hardcoded in your request? Or did you expect expect it to come back from your endpoint?Dialectical
Yes I hardcoded it in. I added a token to the "Authorization" header on PostmanLangille
But does your code explicitly take it from the request and adds it to the response? That doesn’t happen automatically, as it would make no sense to return the bearer token to the end user?Dialectical
Yeah when the user logs in, I return a JWT and the client-side app will then use it as the auth token. Is this not a good approach?Langille
Oh I see, that was a silly mistake lol. Thank you for the suggestion regarding the Dependencies as well!Langille
T
1

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).

Teethe answered 26/12, 2022 at 9:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.