Skip to main content

Authentication middleware for FastAPI with JWT and role-based access control

Project description

FastAPI Auth Middleware

A simple and powerful authentication middleware for FastAPI applications with JWT and role-based access control.

Features

  • JWT-based authentication
  • Token generation, verification, and refresh
  • Zero-query authentication for protected routes
  • Role-based access control
  • Easily customizable token extraction

Installation

pip install fastauth

or with poetry

poetry add fastauth

Quick Start

from fastapi import FastAPI, Depends, HTTPException
from fastauth import (
register_auth_middleware,
setup_token_manager,
require_auth,
require_role,
generate_token,
User
)

app = FastAPI()

# Setup token manager
setup_token_manager(
    secret_key="your_secret_key",
    algorithm="HS256",
    access_token_expire_minutes=30,
    refresh_token_expire_days=7
)

# register auth middleware
register_auth_middleware(
    app,
    exclude_paths=["/public", "/login"],
    token_getter=None  # Optional custom token getter
)

# generate token
tokens = generate_token(User(
    id="user123",
    username="admin", 
    roles=["admin"]
))

# Example login endpoint
@app.post("/login")
async def login(username: str, password: str):
    # Your authentication logic here
    # ...
    # If authentication successful, create a user object
    user = User(
        id="user123",
        username=username,
        roles=["user"] # Assign roles as needed
    )
    # Generate tokens
    tokens = generate_token(user)
    return tokens

# Protected route

@app.get("/protected")
async def protected_route(user_data = Depends(require_auth())):
    return {"message": "This is a protected route", "user_id": user_data.user_id}

# Protected route with role-based access control

@app.get("/admin")
async def admin_route(user_data = Depends(require_role(["admin"]))):
    return {"message": "Admin access granted", "user_id": user_data.user_id}

# Route that requires multiple roles (all of them)

@app.get("/super-admin")
async def super_admin_route(user_data = Depends(require_role(["admin", "super"], require_all=True))):
    return {"message": "Super admin access granted", "user_id": user_data.user_id}

# Public route

@app.get("/public")
async def public_route():
    return {"message": "This is a public route"}

Advanced Usage

Custom Token Extraction

You can customize how tokens are extracted from requests:

def custom_token_getter(request):
    # Your custom logic here
    return request.headers.get("X-Custom-Token")

# register auth middleware
register_auth_middleware(app, token_getter=custom_token_getter)

Refresh Tokens

from fastauth import refresh_token
@app.post("/refresh-token")
async def refresh_tokens(refresh_token_str: str, user_id: str):
    # Get user from your database
    user = get_user_from_db(user_id)
    # Create User object from your user model
    auth_user = User(
        id=user.id,
        username=user.username,
        roles=user.roles
    )
    # Refresh the tokens
    new_tokens = refresh_token(refresh_token_str, auth_user)
    return new_tokens

Token Revocation

from fastauth import revoke_token, revoke_all_user_tokens

@app.post("/logout")
async def logout(token: str, user_data = Depends(require_auth())):
    # Revoke the current token
    revoke_token(token)
    return {"message": "Logged out successfully"}

@app.post("/logout-all-devices")
async def logout_all_devices(user_data = Depends(require_auth())):
    # Revoke all tokens for this user
    revoke_all_user_tokens(user_data.user_id)
    return {"message": "Logged out from all devices"}

CSRF Protection

from fastapi import Depends, Cookie, Response
from fastauth import generate_csrf_token, csrf_protection

# Apply CSRF protection middleware to all routes
app.middleware("http")(csrf_protection())

@app.post("/login")
async def login(username: str, password: str, response: Response):
    # Your authentication logic
    # ...
    
    # Generate tokens
    user = User(id="user123", username=username, roles=["user"])
    tokens = generate_token(user)
    
    # Generate CSRF token
    csrf_token = generate_csrf_token(user.id)
    
    # Set CSRF token as cookie
    response.set_cookie(
        key="csrf_token",
        value=csrf_token,
        httponly=True,
        samesite="strict",
        secure=True  # For HTTPS
    )
    
    return tokens

# Protected route with CSRF protection
@app.post("/update-profile", dependencies=[Depends(csrf_protection())])
async def update_profile(data: dict, user_data = Depends(require_auth())):
    # This route is protected by both authentication and CSRF protection
    return {"message": "Profile updated"}

Redis Backend

FastAuth can use Redis for token storage, which is recommended for production environments:

from fastauth import setup_token_manager

# Setup with Redis
setup_token_manager(
    secret_key="your_secret_key",
    algorithm="HS256", 
    redis_url="redis://localhost:6379/0"  # Will use Redis if available
)

Token Rotation

For enhanced security, you can force token rotation which invalidates all previous tokens:

from fastauth import rotate_user_tokens

@app.post("/security/rotate-tokens")
async def rotate_tokens(user = Depends(require_auth())):
    # Get user from your database
    db_user = get_user_from_db(user.user_id)
    
    # Create User object
    auth_user = User(
        id=db_user.id,
        username=db_user.username,
        roles=db_user.roles
    )
    
    # Rotate tokens
    new_tokens = rotate_user_tokens(auth_user)
    
    return new_tokens

Periodic Token Cleanup

Set up automatic cleanup of expired tokens:

from fastapi import FastAPI
from fastauth import setup_token_manager
from fastauth.tasks import setup_periodic_tasks

app = FastAPI()

# Setup token manager
setup_token_manager(
    secret_key="your_secret_key",
    algorithm="HS256"
)

# Setup token cleanup every hour (3600 seconds)
setup_periodic_tasks(app, cleanup_interval_seconds=3600)

License

MIT

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

fast_guardian-0.1.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fast_guardian-0.1.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file fast_guardian-0.1.0.tar.gz.

File metadata

  • Download URL: fast_guardian-0.1.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.10 Linux/6.11.0-1012-azure

File hashes

Hashes for fast_guardian-0.1.0.tar.gz
Algorithm Hash digest
SHA256 883bc886405a85f1ea09e0b9ed13f56d958741d6b73ae22a2f3a04195a754bed
MD5 67abc2ec08d9514ddfd2c1882e4d744d
BLAKE2b-256 e46991259c094315176d3d62bf5d9b71e7de6dbb3e401c3479b293baeacaa065

See more details on using hashes here.

File details

Details for the file fast_guardian-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fast_guardian-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.1 CPython/3.12.10 Linux/6.11.0-1012-azure

File hashes

Hashes for fast_guardian-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9cadd9a45452f3ed1a0fd92c7a431850928030281ac77bcdf101a5f88dcae0d
MD5 47e74cee35bde7c55f02b2e56b9f8dd9
BLAKE2b-256 c7fe7138ec78c70a952f0dbc50ea32bf1a6d4a23b03cc31095c24370fa7318f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page