fastapi-jwt

repository·main·Indexed 41 days ago

https://github.com/k4black/fastapi-jwt

A native FastAPI extension for JWT authentication providing support for access and refresh tokens, JTI tracking, and cookie management. It integrates with FastAPI's security patterns and OpenAPI schema generation, offering specialized security classes like JwtAccessBearer, JwtAccessCookie, and JwtRefreshBearer to handle token extraction from headers and cookies.

Tokens
5.9K
Snippets
21
Records
24
Agent score
99%

What's inside fastapi-jwt

  1. Features of fastapi-jwt

    main

    fastapi-jwt provides the following capabilities:

    • OpenAPI schema generation: Automatically integrates with FastAPI's documentation.
    • Native FastAPI integration: Uses standard FastAPI security patterns.
    • Access/Refresh JWT: Supports both access and refresh token workflows.
    • JTI: Supports JWT ID (JTI) for token tracking.
    • Cookie setting: Ability to set JWTs in browser cookies.
  2. Configure security objects manually

    main

    You can instantiate security objects (like JwtAccessBearerCookie) manually to define how tokens are validated and extracted. Key parameters include:

    • secret_key: The secret used for signing.
    • auto_error: Boolean determining if an error should be raised automatically if the token is missing/invalid.
    • access_expires_delta: A timedelta defining the validity period of the access token.
    • refresh_expires_delta: A timedelta defining the validity period of the refresh token.
    access_security = JwtAccessBearerCookie(
        secret_key="other_secret_key",
        auto_error=True,
        access_expires_delta=timedelta(hours=1),
        refresh_expires_delta=timedelta(days=1),
    )
  3. Set up a development environment for fastapi-jwt

    main

    It is recommended to use a virtual environment (venv) for development.

    To create and activate a virtual environment, run:

    python3 -m venv .venv
    source .venv/bin/activate

    To install the necessary development dependencies (including docs and test extras), use:

    python -m pip install .[docs,test]
    python3 -m venv .venv
    source .venv/bin/activate
    python -m pip install .[docs,test]
  4. Run the documentation development server

    main

    Documentation is located in the docs/ directory and managed with mkdocs. To run a local development server with auto-reload, use:

    mkdocs serve --config-file docs/mkdocs.yml

    Note: The server automatically restarts for changes in docs/* files. However, if you edit README.md or CONTRIBUTING.md, you must manually restart the server.

    mkdocs serve --config-file docs/mkdocs.yml
  5. Install fastapi-jwt

    main

    Install fastapi-jwt via pip. You must specify a backend dependency. The library automatically selects the backend based on priority: authlib is preferred, followed by python_jose (which is deprecated).

    To install with the recommended authlib backend:

    pip install fastapi-jwt[authlib]

    To install with the deprecated python_jose backend:

    pip install fastapi-jwt[python_jose]
    pip install fastapi-jwt[authlib]
  6. Use fastapi-jwt for JWT authentication

    main

    The library is designed to be used as a standard FastAPI security feature. You can use JwtAccessBearer to manage token creation and cookie setting, and JwtAuthorizationCredentials to inject the decoded token payload into your route dependencies.

    Key components:

    • JwtAccessBearer: Handles token generation (create_access_token) and cookie management (set_access_cookie).
    • JwtAuthorizationCredentials: A type used with FastAPI's Security dependency to access the decoded JWT payload as a dictionary.
    from fastapi import FastAPI, Security, Response
    from fastapi_jwt import JwtAuthorizationCredentials, JwtAccessBearer
    
    app = FastAPI()
    # Initialize the bearer with your secret key
    access_security = JwtAccessBearer(secret_key="secret_key", auto_error=True)
    
    @app.post("/auth")
    def auth():
        # Create a token with a subject payload
        subject = {"username": "username", "role": "user"}
        return {"access_token": access_security.create_access_token(subject=subject)}
    
    @app.post("/auth_cookie")
    def auth(response: Response):
        # Create a token and set it as a cookie in the response
        subject = {"username": "username", "role": "user"}
        access_token = access_security.create_access_token(subject=subject)
        access_security.set_access_cookie(response, access_token)
        return {"access_token": access_token}
    
    @app.get("/users/me")
    def read_current_user(
        credentials: JwtAuthorizationCredentials = Security(access_security),
    ):
        # Access the payload directly from the credentials object
        return {"username": credentials["username"], "role": credentials["role"]}
  7. Run linting and testing for fastapi-jwt

    main

    To maintain code quality, use the following commands to run linters and tests:

    Linting:

    • flake8: Check for style violations.
    • mypy: Perform static type checking on the fastapi_jwt package.
    • isort: Check if imports are sorted correctly.

    Testing:

    • pytest: Run the test suite. It is recommended to cover extreme cases, high load, multithreaded scenarios, and incorrect inputs.

    Auto-fixing: To automatically sort imports and apply PEP8 formatting, run:

    python -m isort .
    python -m flake8 .
    python -m mypy fastapi_jwt
    python -m isort . --check
    python -m pytest
    python -m isort .
  8. Build and publish the fastapi-jwt package

    main

    Building a Wheel

    To build a wheel and inspect its contents:

    python3 -m pip wheel . --no-deps --wheel-dir dist
    tar --list -f dist/fastapi-jwt-0.0.1-py3-none-any.whl

    Publishing to PyPI

    To upload the built distributions to PyPI or TestPyPI, use twine:

    To TestPyPI:

    twine upload -r testpypi dist/*

    To PyPI:

    twine upload dist/*
    python3 -m pip wheel . --no-deps --wheel-dir dist
    twine upload -r testpypi dist/*
    twine upload dist/*
  9. Create security objects from existing instances

    main

    To avoid redundant configuration, you can derive new security objects from existing ones using two patterns:

    1. Copy all parameters: Use .from_other(source_object) to create a new security object (e.g., a refresh security object) that inherits all settings from an existing one (e.g., an access security object).
    2. Rewrite specific parameters: Use .from_other(source_object, **overrides) to create a new object that inherits most settings but allows you to override specific keys like secret_key or auto_error.
    # Create refresh_security by copying all params from access_security
    refresh_security = JwtRefreshBearer.from_other(access_security)
    
    # Create a new access security by copying access_security but overriding specific params
    other_access_security = JwtAccessCookie.from_other(
        access_security, 
        secret_key='!key!', 
        auto_error=False
    )
  10. Deploy documentation to GitHub Pages

    main

    To build and deploy the documentation to GitHub Pages without versioning, run:

    mkdocs build --config-file docs/mkdocs.yml
    mkdocs gh-deploy --config-file docs/mkdocs.yml
    mkdocs build --config-file docs/mkdocs.yml
    mkdocs gh-deploy --config-file docs/mkdocs.yml