Rate Limiting¶
fastapi-fullauth provides two levels of rate limiting:
- Auth rate limits — per-route limits on login, register, and password reset (enabled by default)
- Global rate limit middleware — limits all requests per IP (disabled by default)
Both support in-memory and Redis backends.
Auth rate limits¶
Enabled by default. Protects auth endpoints from brute force:
| Route | Default limit | Config |
|---|---|---|
| Login | 5 per minute | AUTH_RATE_LIMIT_LOGIN |
| Register | 3 per minute | AUTH_RATE_LIMIT_REGISTER |
| Password reset | 3 per minute | AUTH_RATE_LIMIT_PASSWORD_RESET |
from fastapi_fullauth import FullAuth, FullAuthConfig
fullauth = FullAuth(
adapter=adapter,
config=FullAuthConfig(
SECRET_KEY="...",
AUTH_RATE_LIMIT_LOGIN=10, # 10 login attempts per window
AUTH_RATE_LIMIT_REGISTER=5, # 5 registrations per window
AUTH_RATE_LIMIT_WINDOW_SECONDS=120, # 2-minute window
),
)
Disable entirely:
fullauth = FullAuth(
adapter=adapter,
config=FullAuthConfig(
SECRET_KEY="...",
AUTH_RATE_LIMIT_ENABLED=False,
),
)
Global rate limit middleware¶
Limits all requests per client IP. Disabled by default:
fullauth = FullAuth(
adapter=adapter,
config=FullAuthConfig(
SECRET_KEY="...",
RATE_LIMIT_ENABLED=True,
),
)
fullauth.init_app(app) # middleware is auto-added
Default: 60 requests per 60 seconds per IP.
Response headers are included on every response:
When the limit is exceeded, a 429 Too Many Requests response is returned.
Proxy support¶
Behind a reverse proxy (Nginx, Cloudflare, AWS ALB), request.client.host is the proxy's IP, not the real user's. Configure trusted proxy headers so rate limiting works correctly:
fullauth = FullAuth(
adapter=adapter,
config=FullAuthConfig(
SECRET_KEY="...",
TRUSTED_PROXY_HEADERS=["X-Forwarded-For"],
),
)
Warning
Only list headers you trust. If your server is directly exposed to the internet (no proxy), leave this empty — otherwise users can spoof their IP via the header.
When X-Forwarded-For contains a chain (e.g. 1.2.3.4, 10.0.0.1), the first IP (original client) is used.
This setting applies to both auth rate limits and the global rate limit middleware.
Redis backend¶
For multi-process or multi-server deployments, use the Redis backend:
fullauth = FullAuth(
adapter=adapter,
config=FullAuthConfig(
SECRET_KEY="...",
RATE_LIMIT_ENABLED=True,
RATE_LIMIT_BACKEND="redis",
REDIS_URL="redis://localhost:6379/0",
),
)
The in-memory backend is per-process. Redis shares state across all workers/servers.
Custom backends¶
Register your own lockout or rate limiter backend:
from fastapi_fullauth.protection.lockout import LockoutManager, register_lockout_backend
from fastapi_fullauth.protection.ratelimit import register_rate_limiter_backend
class DatabaseLockoutManager(LockoutManager):
def __init__(self, max_attempts, lockout_seconds, **kwargs):
super().__init__(max_attempts, lockout_seconds)
# your database setup
async def is_locked(self, key: str) -> bool: ...
async def record_failure(self, key: str) -> None: ...
async def clear(self, key: str) -> None: ...
register_lockout_backend("database", DatabaseLockoutManager)
# Then set LOCKOUT_BACKEND="database" in config
The same pattern works for rate limiters with register_rate_limiter_backend().
Manual middleware setup¶
If you need more control, disable auto-middleware and add it yourself: