FastAPIAuth
Authentication for FastAPI applications.
FastAPIAuth
Bases: BaseAuth
Authentication for FastAPI apps.
RECOMMENDED: Use protect_app() to protect your entire application with one line.
Example (RECOMMENDED - protect entire app): from fastapi import FastAPI, Depends from cognito_auth.fastapi import FastAPIAuth
app = FastAPI()
auth = FastAPIAuth()
auth.protect_app(app) # Protects entire app!
@app.get("/")
def index(user: User = Depends(auth.get_auth_user)):
return {"message": f"Welcome {user.email}!"}
Example (Alternative - protect specific routes): from fastapi import FastAPI, Depends from cognito_auth.fastapi import FastAPIAuth
app = FastAPI()
auth = FastAPIAuth()
@app.get("/public")
def public():
return {"message": "Public page"}
@app.get("/protected")
def protected(user: User = Depends(auth.get_auth_user)):
return {"message": f"Welcome {user.email}!"}
Source code in src/cognito_auth/fastapi.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
Functions
protect_app(app)
Protect the entire application with authentication.
This is the RECOMMENDED approach. Call this once after creating your app, and all routes will require authentication. Use get_auth_user() dependency to access the authenticated user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
FastAPI
|
FastAPI application instance |
required |
Example
app = FastAPI() auth = FastAPIAuth() auth.protect_app(app) # One line protects everything!
@app.get("/") def index(user: User = Depends(auth.get_auth_user)): return {"message": f"Welcome {user.email}!"}
Source code in src/cognito_auth/fastapi.py
get_auth_user(request)
Get the authenticated and authorised user for this request.
This method is designed to be used with FastAPI's Depends() for dependency injection.
When using protect_app() (RECOMMENDED), this retrieves the user that was validated by the middleware.
When not using protect_app(), this validates the user on-demand.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
Request
|
FastAPI Request object (automatically injected by Depends) |
required |
Returns:
| Type | Description |
|---|---|
User
|
Authenticated and authorised User |
Raises:
| Type | Description |
|---|---|
HTTPException
|
401 if authentication fails, 403 if unauthorised |
Example
auth.protect_app(app)
@app.get("/protected") def protected_route(user: User = Depends(auth.get_auth_user)): return {"email": user.email}
Source code in src/cognito_auth/fastapi.py
Quick Start
from fastapi import FastAPI, Depends
from cognito_auth import User
from cognito_auth.fastapi import FastAPIAuth
app = FastAPI()
# Auto-loads from environment variables
auth = FastAPIAuth()
auth.protect_app(app) # Protects entire app!
@app.get("/")
def index(user: User = Depends(auth.get_auth_user)):
return {"message": f"Welcome {user.email}!"}
Configuration
FastAPIAuth inherits from BaseAuth and accepts these parameters:
authoriser(optional): Pre-configured Authoriser instance. If not provided, auto-loads from environment variablesredirect_url(optional): Where to redirect unauthorised users (default: "https://gds-idea.click/401.html")region(optional): AWS region (default: "eu-west-2")
from cognito_auth import Authoriser
from cognito_auth.fastapi import FastAPIAuth
# Custom configuration
authoriser = Authoriser.from_lists(allowed_groups=["developers"])
auth = FastAPIAuth(
authoriser=authoriser,
redirect_url="https://myapp.com/unauthorised",
region="us-east-1"
)
Behavior
FastAPIAuth uses dependency injection with Depends(). When authentication or authorisation fails:
- With
protect_app(): Middleware redirects toredirect_urlbefore any route executes - Without
protect_app(): Routes withDepends(auth.get_auth_user)raiseHTTPException(401 for auth failure, 403 for unauthorised)
The user is stored in request.state.user, making it efficient to call get_auth_user() multiple times.
Development Mode
Enable dev mode for local development without ALB:
When dev mode is enabled and headers are missing, get_auth_user() returns a mock user instead of failing.
Customizing the Mock User
To customize the mock user returned in dev mode, create a dev-mock-user.json file in your project root:
{
"email": "developer@example.com",
"sub": "12345678-1234-1234-1234-123456789abc",
"username": "12345678-1234-1234-1234-123456789abc",
"groups": ["developers", "users"]
}
The mock user will use these values instead of the defaults. This is useful for testing different authorisation scenarios.
Available fields:
- email - Mock user's email address
- sub - Mock user's Cognito subject (UUID)
- username - Mock user's username (usually same as sub)
- groups - Mock user's Cognito groups for authorisation testing
See dev-mock-user.example.json in the repository for a complete template with comments.
Alternative config location:
You can specify a custom path via environment variable:
Complete Example
Protect Entire App (Recommended)
from fastapi import FastAPI, Depends
from cognito_auth import User
from cognito_auth.fastapi import FastAPIAuth
app = FastAPI()
# Initialize and protect entire app
auth = FastAPIAuth()
auth.protect_app(app)
@app.get("/")
def index(user: User = Depends(auth.get_auth_user)):
return {
"message": f"Welcome {user.email}!",
"groups": user.groups,
"is_admin": user.is_admin
}
@app.get("/admin")
def admin_only(user: User = Depends(auth.get_auth_user)):
if not user.is_admin:
raise HTTPException(status_code=403, detail="Admin access required")
return {"message": "Admin panel"}
Protect Specific Routes Only
from fastapi import FastAPI, Depends
from cognito_auth import User
from cognito_auth.fastapi import FastAPIAuth
app = FastAPI()
auth = FastAPIAuth()
# Note: NOT calling protect_app()
@app.get("/public")
def public():
return {"message": "Public endpoint"}
@app.get("/protected")
def protected(user: User = Depends(auth.get_auth_user)):
return {"email": user.email}