Ошибка в FastAPI, связанная с HTTPException
Помогите решить проблему:
У меня должно вызываться исключение в случае, если, к примеру истек JWToken - исключение срабатывает и удаляет куки и перенаправляет на страницу авторизации. Но в терминале почему-то пишет, что есть ошибка.
Вот код:
def verify_access_token(token: str):
try:
data = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
except JWTError:
response = RedirectResponse(url="/auth/signin")
response.delete_cookie("access_token")
raise HTTPException(
status_code=status.HTTP_302_FOUND,
detail="Invalid access token",
headers=response.headers,
)
expire = data.get("expires")
if expire is None:
response = RedirectResponse(url="/auth/signin")
response.delete_cookie("access_token")
raise HTTPException(
status_code=status.HTTP_302_FOUND,
detail="Invalid access token",
headers=response.headers,
)
if datetime.utcnow() > datetime.utcfromtimestamp(expire):
response = RedirectResponse(url="/auth/signin")
response.delete_cookie("access_token")
raise HTTPException(
status_code=status.HTTP_302_FOUND,
detail="Invalid access token",
headers=response.headers,
)
return data
и вот такая ошибка:
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
await route.handle(scope, receive, send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/fastapi/routing.py", line 227, in app
solved_result = await solve_dependencies(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/fastapi/dependencies/utils.py", line 621, in solve_dependencies
solved = await call(**sub_values)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/media/aktan/Data/project/washer_machine_bank/auth/authenticate.py", line 26, in authenticate
user = verify_access_token(cookies["access_token"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/media/aktan/Data/project/washer_machine_bank/auth/jwt_handler.py", line 47, in verify_access_token
raise HTTPException(
fastapi.exceptions.HTTPException
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 429, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/fastapi/applications.py", line 276, in __call__
await super().__call__(scope, receive, send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 91, in __call__
await response(scope, receive, sender)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/responses.py", line 171, in __call__
await send({"type": "http.response.body", "body": self.body})
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 65, in sender
await send(message)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/starlette/middleware/errors.py", line 159, in _send
await send(message)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 531, in send
output = self.conn.send(event)
^^^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/h11/_connection.py", line 512, in send
data_list = self.send_with_data_passthrough(event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/h11/_connection.py", line 545, in send_with_data_passthrough
writer(event, data_list.append)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/h11/_writers.py", line 65, in __call__
self.send_data(event.data, write)
File "/home/aktan/.local/share/virtualenvs/washer_machine_bank-WmEfT3O8/lib/python3.11/site-packages/h11/_writers.py", line 91, in send_data
raise LocalProtocolError("Too much data for declared Content-Length")
h11._util.LocalProtocolError: Too much data for declared Content-Length
которая явно указывает что ошибка в этом части кода:
response = RedirectResponse(url="/auth/signin")
response.delete_cookie("access_token")
raise HTTPException(
status_code=status.HTTP_302_FOUND,
detail="Invalid access token",
headers=response.headers,
)
и связана она с использованием response.headers, но при этом она отрабатывается и удаляет куки и перенаправляет на страницу авторизации.
Но если использовать в headers, к примеру, так, то ошибок нету в терминале и все работает:
raise HTTPException(
status_code=status.HTTP_302_FOUND,
detail="Invalid access token",
headers={"Location": "/auth/signin"},
)
В общем для решения проблемы есть 2 пути
raise HTTPException(
status_code=status.HTTP_307_TEMPORARY_REDIRECT,
detail="Invalid access token",
headers={
"location": "/auth/signin",
"set-cookie": 'access_token=""; Max-Age=0; Path=/; SameSite=lax'}
)
и второй вариант:
response = RedirectResponse(url="/auth/signin")
response.delete_cookie("access_token")
return response
но так же нужно еще указать в
@my_router.get("/")
async def get_balance(request: Request, user: str = Depends(authenticate), pool: Pool = Depends(create_db_pool)):
if isinstance(user, RedirectResponse):
return user
так как в user: str = Depends(authenticate) автоматически не может выполнить RedirectResponse и нужно поставить условие
if isinstance(user, RedirectResponse):
return user
тогда все работает и автоматически удаляются ненужные куки и происходит переадресация и в терминале не выходят ошибки. Эти два варианта успешна работают и не вызывают ошибки. Но остановился на втором варианте решение проблемы