fastapi-auth-patterns

FastAPI Authentication Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "fastapi-auth-patterns" with this command: npx skills add vanman2024/ai-dev-marketplace/vanman2024-ai-dev-marketplace-fastapi-auth-patterns

FastAPI Authentication Patterns

Purpose: Autonomously implement, validate, and debug FastAPI authentication systems with multiple strategies.

Activation Triggers:

  • Implementing user authentication

  • Securing API endpoints

  • JWT token generation/validation issues

  • OAuth2 flow configuration

  • Permission and role-based access control

  • Supabase authentication integration

  • Authentication errors (401, 403)

  • Password hashing and security

Key Resources:

  • scripts/setup-jwt.sh

  • Initialize JWT authentication system

  • scripts/validate-auth.sh

  • Validate authentication configuration

  • templates/jwt_auth.py

  • Complete JWT authentication implementation

  • templates/oauth2_flow.py

  • OAuth2 password flow with scopes

  • templates/supabase_auth.py

  • Supabase integration for FastAPI

  • examples/protected_routes.py

  • Protected endpoint patterns

  • examples/permission_system.py

  • Role and permission-based access

Authentication Strategies

  1. JWT Token Authentication

Use When:

  • Need stateless authentication

  • Building API for mobile/web clients

  • Require token expiration control

  • Implementing refresh token patterns

Setup:

./scripts/setup-jwt.sh

Core Components:

  • Password hashing with Argon2 (pwdlib)

  • JWT token generation with expiration

  • Token validation and user extraction

  • Secure secret key management

Implementation Pattern:

Hash passwords (never store plaintext)

password_hash = PasswordHash.recommended() hashed = password_hash.hash(plain_password)

Generate JWT token

def create_access_token(data: dict, expires_delta: timedelta): to_encode = data.copy() expire = datetime.now(timezone.utc) + expires_delta to_encode.update({"exp": expire}) return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")

Validate token and extract user

async def get_current_user(token: str = Depends(oauth2_scheme)): payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) username = payload.get("sub") return get_user(username)

Key Points:

  • Use environment variables for SECRET_KEY

  • Default token expiration: 30 minutes

  • Store username in "sub" claim

  • Validate token signature and expiration

  1. OAuth2 Password Flow

Use When:

  • Building first-party applications

  • Need username/password authentication

  • Following OAuth2 standards

  • Integrating with OpenAPI documentation

Template: templates/oauth2_flow.py

Flow:

  • User submits credentials via OAuth2PasswordRequestForm

  • Server verifies password hash

  • Server returns signed JWT access token

  • Client includes token in Authorization header

Security Scheme:

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.post("/token") async def login(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(form_data.username, form_data.password) access_token = create_access_token(data={"sub": user.username}) return {"access_token": access_token, "token_type": "bearer"}

  1. OAuth2 Scopes (Permissions)

Use When:

  • Need fine-grained permission control

  • Implementing role-based access

  • Building multi-tenant systems

  • Following least-privilege principle

Template: See templates/oauth2_flow.py (includes scopes)

Define Scopes:

oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", scopes={ "me": "Read information about current user", "items": "Read items", "items:write": "Create and modify items" } )

Encode Scopes in Token:

During login, add user's scopes to token

token_data = {"sub": username, "scopes": user.scopes} access_token = create_access_token(token_data)

Protect Endpoints with Scopes:

async def get_current_user( security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme) ): # Validate token has required scopes for scope in security_scopes.scopes: if scope not in token_data.scopes: raise HTTPException(401, "Not enough permissions")

@app.get("/users/me/items/") async def read_items( current_user: User = Security(get_current_active_user, scopes=["items"]) ): return current_user.items

  1. Supabase Authentication

Use When:

  • Using Supabase as backend

  • Need managed authentication service

  • Want OAuth providers (Google, GitHub, etc.)

  • Require user management dashboard

Template: templates/supabase_auth.py

Setup:

from supabase import create_client, Client

supabase: Client = create_client( os.getenv("SUPABASE_URL"), os.getenv("SUPABASE_KEY") )

Sign Up:

Email/password signup

response = supabase.auth.sign_up({ "email": "user@example.com", "password": "secure_password", "options": {"data": {"full_name": "John Doe"}} })

Sign In:

response = supabase.auth.sign_in_with_password({ "email": "user@example.com", "password": "secure_password" }) access_token = response.session.access_token

Validate Token in FastAPI:

async def get_current_user(token: str = Depends(oauth2_scheme)): # Validate Supabase JWT token user = supabase.auth.get_user(token) return user

Integration Pattern:

  • Store Supabase session in HTTP-only cookies (server-side)

  • Use PKCE flow for OAuth providers

  • Implement token refresh logic

  • Leverage Supabase RLS policies for data access

Validation Workflow

  1. Run Authentication Validator

./scripts/validate-auth.sh

Checks Performed:

  • ✅ Required packages installed (fastapi, python-jose[cryptography], passlib[argon2], pwdlib)

  • ✅ Environment variables set (SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES)

  • ✅ Security scheme configured correctly

  • ✅ Password hashing implemented

  • ✅ Token generation and validation functions present

  • ✅ Protected endpoints use proper dependencies

  1. Common Issues & Fixes

Missing SECRET_KEY:

Generate secure random key

openssl rand -hex 32

Add to .env

echo 'SECRET_KEY=your_generated_key' >> .env

Token Expired (401):

  • Increase ACCESS_TOKEN_EXPIRE_MINUTES

  • Implement refresh token pattern

  • Check server/client time sync

Invalid Credentials:

  • Verify password hashing algorithm matches

  • Check user exists in database

  • Validate password comparison logic

Missing Permissions (403):

  • Verify user has required scopes

  • Check scope encoding in token

  • Validate SecurityScopes configuration

Supabase Connection Failed:

  • Verify SUPABASE_URL and SUPABASE_KEY

  • Check project settings in Supabase dashboard

  • Validate network connectivity

Protected Routes Pattern

Example: examples/protected_routes.py

Public endpoint (no auth)

@app.get("/") async def root(): return {"message": "Public endpoint"}

Protected endpoint (requires authentication)

@app.get("/users/me") async def read_users_me(current_user: User = Depends(get_current_user)): return current_user

Protected with specific permission

@app.post("/items/") async def create_item( item: Item, current_user: User = Security(get_current_active_user, scopes=["items:write"]) ): return create_item_for_user(current_user, item)

Admin-only endpoint

@app.delete("/users/{user_id}") async def delete_user( user_id: int, current_user: User = Depends(get_current_admin_user) ): return delete_user_by_id(user_id)

Permission System Pattern

Example: examples/permission_system.py

Role-Based Access Control (RBAC):

class Role(str, Enum): ADMIN = "admin" USER = "user" GUEST = "guest"

class User(BaseModel): username: str role: Role permissions: List[str]

def has_permission(user: User, required_permission: str) -> bool: # Admins have all permissions if user.role == Role.ADMIN: return True return required_permission in user.permissions

async def require_permission(permission: str): async def permission_checker(current_user: User = Depends(get_current_user)): if not has_permission(current_user, permission): raise HTTPException(403, f"Permission '{permission}' required") return current_user return permission_checker

Usage

@app.delete("/items/{item_id}") async def delete_item( item_id: int, current_user: User = Depends(require_permission("items:delete")) ): return delete_item_by_id(item_id)

Best Practices

Security:

  • Never store passwords in plaintext

  • Use Argon2 for password hashing (recommended over bcrypt)

  • Store SECRET_KEY in environment variables (never commit)

  • Use HTTPS in production

  • Implement rate limiting on login endpoints

  • Add token refresh mechanism for long sessions

Token Management:

  • Short access token expiration (15-30 minutes)

  • Long refresh token expiration (7-30 days)

  • Rotate refresh tokens on use

  • Implement token revocation list for logout

Scope Design:

  • Use hierarchical scopes (e.g., items, items:read, items:write)

  • Follow least-privilege principle

  • Document all scopes in OpenAPI

  • Validate scopes on every request

Error Handling:

  • Return 401 for authentication failures

  • Return 403 for authorization failures

  • Include WWW-Authenticate header with 401

  • Log authentication attempts for security monitoring

Dependencies

Required Packages:

pip install fastapi pip install python-jose[cryptography] pip install pwdlib[argon2] pip install supabase # If using Supabase

Environment Variables:

SECRET_KEY=your_secret_key_here ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=30

For Supabase

SUPABASE_URL=https://your-project.supabase.co SUPABASE_KEY=your_anon_key

Supported Auth Strategies: JWT, OAuth2 Password Flow, OAuth2 Scopes, Supabase

Version: 1.0.0 FastAPI Compatibility: 0.100+

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

document-parsers

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

stt-integration

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

model-routing-patterns

No summary provided by upstream source.

Repository SourceNeeds Review