I am trying to validate token in fastapi middleware but this seems impossible. As i am thinking middleware needs to make next call although its not required. I am not able to find any good solution to handle token in one go in this python-fastapi backend. Any help is appreciated.
@app.middleware("http")
async def add_middleware_here(request: Request, call_next):
token = request.headers["Authorization"]
try:
verification_of_token = verify_token(token)
if verification_of_token:
response = await call_next(request)
return response
except InvalidSignatureError as er:
raise HTTPException(status_code=401)
My expectation is that it should throw 401 error once wrong token is provided.
Instead it throws 500 with below Exception traceback:
Traceback (most recent call last):
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 385, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\fastapi\applications.py", line 140, in __call__
await super().__call__(scope, receive, send)
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\starlette\applications.py", line 134, in __call__
await self.error_middleware(scope, receive, send)
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\starlette\middleware\errors.py", line 178, in __call__
raise exc from None
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\starlette\middleware\errors.py", line 156, in __call__
await self.app(scope, receive, _send)
File "c:\users\covered\appdata\local\programs\python\python38\lib\site-packages\starlette\middleware\base.py", line 26, in __call__
await response(scope, receive, send)
TypeError: 'NoneType' object is not callable
What kind of behavior do you expect when if verification_of_token: is elsed? Seems like you must raise HTTPException(status_code=401) then.
Also there is also option to use https://fastapi.tiangolo.com/tutorial/dependencies/
What kind of behavior do you expect when
if verification_of_token:is elsed? Seems like you mustraise HTTPException(status_code=401)then.Also there is also option to use https://fastapi.tiangolo.com/tutorial/dependencies/
Actually verification_of_token can be true or false depending on token's validity. I am trying to check token here itself before it goes any further. Also InvalidSignatureError error comes up when token is invalid. Now problem is: this always fails the backend here by going in 500 interval server error other than going in 401 unauthorized error. I want to throw 401 error.
I have updated the above problem with exception traceback
According to middleware docs you must either return response or call_next func. Seems like your middleware is not properly throwing a InvalidSignatureError and if block being ignored. So you return None from your middleware which causes exception
So how should i then check validity of token now?
I'd go for something likes. Not sure how's your verify_token func looks like. But it's how to you how you make it) It doesn't seems like FastAPI issue)
def verify_token(token):
if check_token(token):
return True
else:
return False
@app.middleware("http")
async def add_middleware_here(request: Request, call_next):
token = request.headers["Authorization"]
if verify_token(token):
response = await call_next(request)
return response
else:
raise HTTPException(status_code=401)
I'd go for something likes. Not sure how's your
verify_tokenfunc looks like. But it's how to you how you make it) It doesn't seems like FastAPI issue)def verify_token(token): if check_token(token): return True else: return False @app.middleware("http") async def add_middleware_here(request: Request, call_next): token = request.headers["Authorization"] if verify_token(token): response = await call_next(request) return response else: raise HTTPException(status_code=401)
This totally sounds reasonable but i have already performed this thing and it throws same error as above.
Well, just to be clear I didn鈥檛 tested code above. It was just a graft. Also may be that鈥檚 because you are raising exception instead of returning Response object. Give it a few tries. Also take a look at Dependency based authorization it looks sexy
hey @priyankagupta34 I just came across the same issue, seems weirdly HTTPException doesn't work in middle ware. See https://github.com/tiangolo/fastapi/issues/1125
the comment in there has the solution tho
return Response(content="", status_code=401)
but I agree this is unclear would be good to know if this should be in the documentation or if it's a bug @tiangolo and others think should be addressed. Something like bubbling up if the caught below exception is already of type HTTPException.
This is an intended. So the thing you should do is to return a Response with right status code and message.
See #458