Advanced Authentication
Integrate JWTs, manage complex scopes, and handle user context securely.
JWT Validation & User Context
A common pattern is decoding a JWT, validating it, and attaching the user object to the request state.
import jwt
from fastapi import HTTPException
async def jwt_auth_handler(request: Request, roles: list[str] = None) -> bool:
auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
return False
token = auth_header.split(" ")[1]
try:
# Decode token
payload = jwt.decode(token, "APP_SECRET", algorithms=["HS256"])
# Attach user to request state for endpoint access
request.state.user = payload
# Role Check
if roles:
user_roles = payload.get("roles", [])
has_permission = any(role in user_roles for role in roles)
if not has_permission:
raise HTTPException(status_code=403, detail="Insufficient Permissions")
return True
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")
except jwt.InvalidTokenError:
return False # Invalid tokenAccessing User Data
Data attached to request.state in the auth handler becomes available in your endpoints.
routes/profile.py
class UserProfile(Route):
@auth(True)
async def get(self, request: Request):
# Access user data set by the auth handler
user_id = request.state.user["id"]
return {"id": user_id, "name": request.state.user["name"]}Detailed Signature
def auth(
enabled: bool = True, *,
roles: list[str] = None,
scopes: list[str] = None,
require_all: bool = False,
custom_error: str = None
)- roles: List of required user roles (e.g.,
["admin", "mod"]). - scopes: List of required OAuth scopes (e.g.,
["read:users"]). - require_all: If
True, user must have all listed roles/scopes. IfFalse, any match grants access. - custom_error: Custom message for
403 Forbiddenresponses.