Ошибка в FastAPI, связанная с HTTPException

Рейтинг: 0Ответов: 0Опубликовано: 10.05.2023

Помогите решить проблему:

У меня должно вызываться исключение в случае, если, к примеру истек 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

тогда все работает и автоматически удаляются ненужные куки и происходит переадресация и в терминале не выходят ошибки. Эти два варианта успешна работают и не вызывают ошибки. Но остановился на втором варианте решение проблемы

Ответы

Ответов пока нет.