[Python] FastAPI TestClient Not Passing Cookies Correctly in Refresh Token Test

Discussão em 'Python' iniciado por Stack, Março 12, 2025.

  1. Stack

    Stack Membro Participativo

    I'm developing a personal project for learning purposes, using Prisma ORM and FastAPI as the main technologies.

    I'm encountering an issue where my refresh token endpoint returns a 401 error, even though the token is correctly passed via cookies.

    After researching, I found that handling tokens within dependencies in FastAPI can sometimes cause issues. To work around this, I tried using dependency overrides, but now I'm getting a 422 error, even though the request does not require a body—only the cookie.

    conftest.py

    import os
    import subprocess

    from fastapi.testclient import TestClient

    import redis

    from taskcollabapi.app import app

    import pytest

    from testcontainers.postgres import PostgresContainer
    from testcontainers.redis import RedisContainer


    # ---------------------------------- Database Containers ---------------------------------
    @pytest.fixture(scope='session')
    def postgres_container():
    with PostgresContainer('postgres:17') as postgres:
    postgres_url = postgres.get_connection_url()
    postgres_url = postgres_url.replace("postgresql+psycopg2", "postgresql")

    os.environ['DATABASE_URL'] = postgres_url
    yield postgres


    @pytest.fixture(scope='session')
    def redis_container():
    with RedisContainer('redis:latest') as redis:
    host = redis.get_container_host_ip()
    port = redis.get_exposed_port(6379)

    os.environ['REDIS_HOST'] = host
    os.environ['REDIS_PORT'] = str(port)

    yield redis

    # ------------------------------------ Server Fixture ------------------------------------
    @pytest.fixture(scope='module')
    def client(postgres_container, redis_container):
    # Resetting the database before each module
    subprocess.run(['poetry', 'run', 'prisma', 'db', 'push'])

    redis_client = redis.Redis(
    host=os.environ['REDIS_HOST'],
    port=int(os.environ['REDIS_PORT']),
    db=0
    )
    redis_client.flushall() # Remove all data from Redis
    redis_client.close()

    with TestClient(app) as client:
    yield client


    subprocess.run(['poetry', 'run', 'prisma', 'migrate', 'reset', '--force'])


    # ---------------------------------- alciliary functions ---------------------------------
    @pytest.fixture(scope='module')
    def register_user(client: TestClient):
    response = client.post('/auth/signUp', json={
    'name': 'Maria Madalena',
    'email': 'maria@gmail.com',
    'password': '12344321'
    })

    yield {'email': 'maria@gmail.com', 'password': '12344321'}




    test_refresh_token.py

    from fastapi.testclient import TestClient
    import pytest

    @pytest.fixture(scope='module')
    def sign_in_user(client: TestClient, register_user):
    response = client.post('auth/signIn', json=register_user)
    assert response.status_code == 200

    refresh_token = response.cookies.get("refresh_token")


    print(refresh_token)

    return refresh_token


    def test_refresh_token_success(client: TestClient, sign_in_user):
    response = client.post(
    '/auth/refresh',
    cookies={'refresh_token': sign_in_user}
    )

    assert response.status_code == 200

    # data = response.json()

    # assert data['code'] == 'TOKEN_CREATED'

    # assert 'access_token' in data['data']
    # assert 'token_type' in data['data']


    controller:

    @router.post('/refresh', status_code=200, response_model=CreateTokenResposeSchema)
    async def refresh_token(
    refress_token_data: TokenDataType = Depends(verify_refresh_token),
    ):
    return await service.refresh_token(refress_token_data)


    services:

    async def refresh_token(refresh_token: TokenDataType) -> CreateTokenResposeDict:
    payload = refresh_token[1]

    # Create a new access token
    new_access_token = security.create_access_token(payload.sub)

    return {
    'status': 200,
    'code': 'TOKEN_CREATED',
    'message': 'the token has been recreated',
    'data': TokenData(access_token=new_access_token, token_type='Bearer'),
    }


    dependencies:

    async def verify_refresh_token(request: Request) -> TokenDataType:
    refresh_token = request.cookies.get('refresh_token')
    # Validate the refresh token
    if not refresh_token:
    raise InvalidTokenError('Missing refresh token')

    payload = security.decode_token(refresh_token)
    if not payload:
    raise InvalidTokenError('Invalid or expired refresh token')

    if await auth_repo.token_in_blocklist(payload.jti):
    raise InvalidTokenError('token revoked')

    return (refresh_token, payload)



    the project can be found here: https://github.com/yudur/TaskCollabAPI

    I expected return 200 but this did not occur because for some reason the cookie validation is not happening in my testClient

    Continue reading...

Compartilhe esta Página