FastAPI MultiAuth¶
Composable authentication sources for FastAPI. You write the function that decides who a credential belongs to; the library extracts the credential, combines several schemes on one route, and declares all of it in OpenAPI.
No user model, no database coupling, no ready-made /login routes. Your store, your rules.
Installation¶
Optional extras: jwt for JWTValidator, oauth for the OAuth login helpers.
A first route¶
One route that accepts either an API token or a browser session cookie:
import os
from fastapi import FastAPI, Security
from fastapi_multiauth import (
APIKeyCookieAuth,
HTTPBearerAuth,
MultiAuth,
UnauthorizedError,
hash_token,
)
SECRET_KEY = os.environ["SECRET_KEY"]
USERS = {"1": {"id": "1", "name": "alice"}}
TOKENS = {hash_token("user_alice-token"): "1"}
async def validate_token(token: str) -> dict:
user_id = TOKENS.get(hash_token(token))
if user_id is None:
raise UnauthorizedError()
return USERS[user_id]
async def validate_session(user_id: str) -> dict:
if user_id not in USERS:
raise UnauthorizedError()
return USERS[user_id]
bearer = HTTPBearerAuth(validator=validate_token, prefix="user_")
session = APIKeyCookieAuth(
name="__Host-session", validator=validate_session, secret_key=SECRET_KEY
)
auth = MultiAuth(bearer, session)
app = FastAPI()
@app.get("/me")
async def me(user: dict = Security(auth)):
return user
- A validator is a function you write: it receives the credential and returns the user, or raises to refuse it.
HTTPBearerAuth(..., prefix="user_")readsAuthorization: Bearer user_...tokens.APIKeyCookieAuthreads a signed cookie; your validator only sees the value once the signature checks out.SECRET_KEYmust hold at least 32 random bytes, e.g. fromsecrets.token_urlsafe(32).MultiAuthuses whichever one the request carries, and both appear in/docs.
What you get¶
-
Every standard scheme
Bearer tokens, signed cookies, API keys, HTTP Basic, OAuth 2.0 and OpenID Connect.
-
Several schemes, one route
MultiAuthtries sources in order and documents all of them. -
Step-up authentication
Demand a recent or stronger login on sensitive routes.
-
Fails closed
Weak secrets, missing HTTPS and unenforceable scopes are refused, never skipped.
Coming from fastapi.security, fastapi-users or AuthX? See the comparison.