Skip to main content

FastAPI authentication library with JWT access/refresh tokens, sync & async SQLAlchemy support, built-in auth routes (register/login/refresh/me), secure password hashing, and cookie/header token support.

Project description

FastAPI JWT Auth Kit

PyPI version Python License Downloads

FastAPI authentication library with JWT access/refresh tokens, sync & async SQLAlchemy support, built-in auth routes (register/login/refresh/me), secure password hashing, and cookie/header token support.

Complete authentication toolkit for FastAPI with JWT, designed for both sync and async SQLAlchemy backends. Provides batteries-included auth services, FastAPI routers, token utilities, and a clean protocol-driven repository interface.

Highlights

  • JWT access + refresh tokens with rotation
  • Sync and async SQLAlchemy adapters
  • Drop-in FastAPI routers for register, login, refresh, logout, and /me
  • Cookie and Authorization header support
  • Strong typing and protocol-based extensibility
  • Works with your own User model

Package Layout

packages/authkit/src/authkit/
  fastapi/      # FastAPI router builders + schemas
  ext/          # SQLAlchemy protocol adapters (sync/async)
  authenticator.py
  service.py
  tokens.py
  hashing.py
  settings.py
  extractors.py

Installation

From this repo

uv sync

In your project

pip install fastapi-jwt-authkit

The PyPI package name is fastapi-jwt-authkit, the import name is authkit.

Typing support

Type information (.pyi + py.typed) is bundled with the package for IDEs and static type checkers.

Quickstart (Async)

from fastapi import FastAPI
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker

from authkit import AuthSettings
from authkit.fastapi.routers import build_auth_router_async

from your_app.models import Base, User

DATABASE_URL = "sqlite+aiosqlite:///./app.db"
engine = create_async_engine(DATABASE_URL, echo=False)
SessionLocal = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_session():
    async with SessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise

settings = AuthSettings(secret_key="change-me", cookie_secure=False)

app = FastAPI()
auth_router = build_auth_router_async(
    settings=settings,
    get_session=get_session,
    user_model=User,
)
app.include_router(auth_router, prefix="/auth", tags=["auth"])

Quickstart (Sync)

from fastapi import FastAPI
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from authkit import AuthSettings
from authkit.fastapi.routers import build_auth_router_sync

from your_app.models import Base, User

DATABASE_URL = "sqlite:///./app.db"
engine = create_engine(DATABASE_URL, echo=False)
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)

def get_session():
    session = SessionLocal()
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()

settings = AuthSettings(secret_key="change-me", cookie_secure=False)

app = FastAPI()
auth_router = build_auth_router_sync(
    settings=settings,
    get_session=get_session,
    user_models=User,
)
app.include_router(auth_router, prefix="/auth", tags=["auth"])

Core Concepts

AuthSettings

All auth behavior is configured via AuthSettings:

AuthSettings(
    secret_key="your-secret",
    algorithm="HS256",
    access_minutes=15,
    refresh_days=7,
    accept_header=True,
    accept_cookie=True,
    set_cookie_on_login=True,
    cookie_secure=True,
    cookie_samesite="lax",
)

AuthService / AsyncAuthService

Business logic for creating users, authenticating, and issuing tokens. Uses a repository protocol so you can plug in your own persistence layer.

SQLAlchemy Adapters

  • SQLAlchemySyncUserProtocol
  • SQLAlchemyAsyncUserProtocol

These adapters expect a SQLAlchemy model with the following fields:

class User(Base):
    id: int
    email: str
    username: str
    password_hash: str
    is_active: bool
    is_staff: bool
    is_superuser: bool

API Endpoints

When you include the auth router with prefix /auth, the following endpoints are available:

Method Path Description
POST /auth/register Create a new user
POST /auth/login Authenticate + issue tokens
POST /auth/refresh Refresh access token
POST /auth/logout Clear auth cookies
GET /auth/me Get current user

Request/Response Schemas

Register

{ "email": "user@example.com", "username": "user", "password": "secret" }

Login

{ "username_or_email": "user", "password": "secret" }

Token Response

{ "access_token": "jwt", "refresh_token": "jwt" }

Cookies and Headers

AuthSettings controls where tokens are accepted and how they are stored:

  • accept_header: allow Authorization: Bearer <token>
  • accept_cookie: allow cookies
  • set_cookie_on_login: set cookies on successful login

Cookie names and TTL are customizable with: cookie_name_access, cookie_name_refresh, cookie_max_age_access, cookie_max_age_refresh.

Security Considerations

  • Use a strong secret_key and rotate regularly.
  • Set cookie_secure=True in production (HTTPS only).
  • Consider cookie_samesite="strict" for web apps with tight CSRF control.
  • Short access token TTLs with longer refresh TTLs are recommended.

Production Checklist

  • secret_key stored in a secure secret manager
  • HTTPS enforced
  • cookie_secure=True, cookie_samesite set per app policy
  • Rotate JWT secret or use KMS-backed signing
  • Enable logging around login and refresh flows
  • Implement account lockout or rate limiting at the API gateway
  • Configure backups for the user datastore

Compatibility

  • Python: 3.10+
  • FastAPI: 0.110+
  • SQLAlchemy: 2.x

Observability

This library raises standard HTTPException errors. For production:

  • Add structured logging around auth endpoints
  • Add tracing/metrics at the FastAPI middleware layer

Versioning

Follows semantic versioning: MAJOR.MINOR.PATCH.

Testing

Run the full test suite:

uv run pytest tests/ -v

All tests are under tests/ and cover tokens, hashing, services, and router integration (sync + async).

Examples

Working example apps are provided:

  • examples/async_app.py
  • examples/sync_app.py

Run:

uv run python -m examples.async_app
uv run python -m examples.sync_app

Extending the Repo Layer

Implement the repo protocol if you use a different persistence layer:

class MyRepo:
    def get_by_id(self, user_id: int): ...
    def get_by_email_or_username(self, value: str): ...
    def create_user(self, *, email: str, username: str, password: str,
                    is_staff: bool, is_active: bool, is_superuser: bool): ...

Async version must expose the same methods as async def.

Typing Notes

Type information is bundled with the package (.pyi + py.typed). If your IDE or type checker does not pick it up, ensure:

  • Your tooling supports PEP 561

Troubleshooting

Bcrypt errors on Windows

If you see bcrypt backend errors during hashing, ensure you have bcrypt<5 installed. This repo pins it accordingly in pyproject.toml.

SQLite in-memory tests

In-memory SQLite needs a StaticPool so all sessions share the same DB connection. The tests already handle this.

License

MIT (see LICENSE).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_jwt_authkit-1.0.0.tar.gz (153.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_jwt_authkit-1.0.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_jwt_authkit-1.0.0.tar.gz.

File metadata

  • Download URL: fastapi_jwt_authkit-1.0.0.tar.gz
  • Upload date:
  • Size: 153.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fastapi_jwt_authkit-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fcf1038819dbb6ee8ab716eaf4904e891f985dea7f8b2a3025f9171138e99387
MD5 ad10ea87354eac3a61e931cd0056ca86
BLAKE2b-256 ef36802c354e11cc35542bf465630cda7dac6a37befe89209c0826c20623c583

See more details on using hashes here.

File details

Details for the file fastapi_jwt_authkit-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: fastapi_jwt_authkit-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fastapi_jwt_authkit-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5814b19c01f48f72bb07e40ce09e836fd2e3abf869b1565afa96289181dc82c8
MD5 f149605585fd29d433e1c51f976e375d
BLAKE2b-256 9934352f80794fbcf732378064ee0588d6e23236eff2d4af768841ad198035aa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page