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
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 isauthkit.
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
SQLAlchemySyncUserProtocolSQLAlchemyAsyncUserProtocol
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: allowAuthorization: Bearer <token>accept_cookie: allow cookiesset_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_keyand rotate regularly. - Set
cookie_secure=Truein 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_keystored in a secure secret manager - HTTPS enforced
-
cookie_secure=True,cookie_samesiteset 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.pyexamples/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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcf1038819dbb6ee8ab716eaf4904e891f985dea7f8b2a3025f9171138e99387
|
|
| MD5 |
ad10ea87354eac3a61e931cd0056ca86
|
|
| BLAKE2b-256 |
ef36802c354e11cc35542bf465630cda7dac6a37befe89209c0826c20623c583
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5814b19c01f48f72bb07e40ce09e836fd2e3abf869b1565afa96289181dc82c8
|
|
| MD5 |
f149605585fd29d433e1c51f976e375d
|
|
| BLAKE2b-256 |
9934352f80794fbcf732378064ee0588d6e23236eff2d4af768841ad198035aa
|