Skip to content

Security Patterns

JWT Authentication

from datetime import datetime, timedelta

import jwt


def create_access_token(user_id: UUID, expires_delta: timedelta) -> str:
    payload = {
        "sub": str(user_id),
        "exp": datetime.utcnow() + expires_delta,
        "type": "access",
    }
    return jwt.encode(payload, settings.secret_key.get_secret_value(), algorithm="HS256")

Current User Dependency

from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")


async def get_current_user(
    token: str = Depends(oauth2_scheme),
    user_service: UserService = Depends(get_user_service),
) -> User:
    try:
        payload = jwt.decode(
            token, settings.secret_key.get_secret_value(), algorithms=["HS256"]
        )
        user_id = UUID(payload["sub"])
    except (jwt.InvalidTokenError, KeyError, ValueError):
        raise UnauthorizedError("Invalid or expired token")

    user = await user_service.get_user(user_id)
    if not user.is_active:
        raise ForbiddenError("Account is deactivated")
    return user


async def get_current_active_user(
    user: User = Depends(get_current_user),
) -> User:
    return user

CORS Configuration

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Rate Limiting

Use slowapi or custom middleware to protect expensive endpoints:

from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)


@router.post("/auth/login")
@limiter.limit("5/minute")
async def login(request: Request, credentials: LoginRequest):
    ...

See Also