Quickstart¶
Minimal app¶
from fastapi import FastAPI, Depends
from authwarden import AuthWarden, WardenConfig, MemoryUserStore
config = WardenConfig(
secret_key="change-me-to-a-real-32-byte-secret",
require_email_verification=False, # skip for this example
)
store = MemoryUserStore() # swap for your own AbstractUserStore in production
warden = AuthWarden(config=config, user_store=store)
app = FastAPI()
app.include_router(warden.router, prefix="/auth", tags=["auth"])
@app.get("/profile")
async def profile(user=Depends(warden.current_user)):
return {"id": user.id, "email": user.email}
uvicorn main:app --reload
Open http://127.0.0.1:8000/docs. You now have 20 working endpoints under /auth, plus an Authorize button in Swagger UI for testing protected routes with a Bearer token.
Try it end-to-end¶
# Register
curl -X POST http://127.0.0.1:8000/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "password": "strongpassword123"}'
# Login
curl -X POST http://127.0.0.1:8000/auth/login \
-H "Content-Type: application/json" \
-d '{"identifier": "you@example.com", "password": "strongpassword123"}'
# → returns access_token, refresh_token, and user
# Use the access_token on a protected route
curl http://127.0.0.1:8000/profile \
-H "Authorization: Bearer <access_token>"
Adding a real database¶
MemoryUserStore is for development and testing only — it forgets everything on restart. Swap in your own store by implementing AbstractUserStore:
warden = AuthWarden(config=config, user_store=MySQLAlchemyUserStore(session_factory))
See Core Concepts → User Store for full adapter examples.
Protecting your own routes¶
from fastapi import Depends
@app.get("/admin/dashboard")
async def dashboard(_=Depends(warden.require_roles("admin"))):
...
@app.post("/posts")
async def create_post(_=Depends(warden.require_scopes("posts:write"))):
...
See Permissions for the full role/scope model.
Turning on more flexibility¶
Everything below is one config change away — see the full Configuration Reference:
config = WardenConfig(
secret_key="...",
verification_method="otp", # OTP instead of email link
verification_channels=["email", "sms"], # send to both
login_identifier_fields=["email", "username", "phone"],
enable_mfa=True,
oauth_providers={
"google": OAuthProviderConfig(
client_id="...", client_secret="...", redirect_uri="https://yourapp.com/cb/google"
),
},
)