k4black / fastapi-jwt

FastAPI native extension, easy and simple JWT auth
https://k4black.github.io/fastapi-jwt/
MIT License
123 stars 16 forks source link

Possible to disable JWT authorization for testing? #24

Closed f-fuchs closed 8 months ago

f-fuchs commented 10 months ago

Hey,

I am using your excellent library to add JWT based authorization to my FastAPI app. But now I am at a point where I would like to add unit test to my project to check my routes. And for this I would like to disable authorization.

Based on my research this should be doable with app.dependency_overrides , see https://fastapi.tiangolo.com/advanced/testing-dependencies/.

But because we are not actually passing a method to Security I am not sure what to override. I tried passing the same Depends(get_access_security()) code with which I created the dependency annotation into the override, but this does not work. Therefore I wanted to ask what exactly I should override or if there is another option to disable authorization for my testing purposes. Below are the relevant snippets from my source code.

config.py

@lru_cache
def get_access_security() -> JwtAccessBearerCookie:
    """Return an JWT access security object to generate and test access tokens.

    Returns:
        JwtAccessBearerCookie: The access security.
    """
    return JwtAccessBearerCookie(
        secret_key=settings.secret_key,
        auto_error=True,
        access_expires_delta=settings.access_expires_delta,
    )

AccessSecurityDependency = Annotated[
    JwtAuthorizationCredentials,
    Depends(get_access_security()),
]

route

 @router.patch(
        "/api/calibration-order/id/{id}",
        response_model=CalibrationOrder,
        response_model_exclude_unset=True,
    )
    async def update_calibration_order_by_id(
        id: str,
        patch: list[dict],
        credentials: AccessSecurityDependency,
    ) -> CalibrationOrder:

py test fixture

@pytest.fixture()
def client_authenticated() -> Generator[TestClient, Any, None]:
    """
    Pytest fixture that yields an instance of TestClient which skips the authentication.

    Yields:
        Generator[TestClient, Any, None]: An instance of the TestClient.
    """

    def get_access_security_override() -> None:
        return None

    app.dependency_overrides[
        Depends(get_access_security())
    ] = get_access_security_override
    with TestClient(app) as c:
        yield c
EvgeniyShell commented 8 months ago

you can try switch auto_error to false

f-fuchs commented 8 months ago

My problem was that I could not override the original security dependency. I guess setting auto_error always to False and adding a new dependency, which I can then override, atop of this library could work. 🤔

But I already choose to just reimplement the functionality as functions instead of classes, so that I can override them with FastAPIs dependency_overrides.

Thanks for the suggestion though 👍