Skip to content

Quick Start

This guide creates a working FastAPI application with signup, login, protected routes, and OAuth — in under 20 lines.

  1. Install

    pip install authfort[fastapi] uvicorn
    pip install authfort[fastapi] uvicorn
  2. Create the app

    main.py
    from contextlib import asynccontextmanager
    from authfort import AuthFort, CookieConfig
    from fastapi import FastAPI, Depends
    
    auth = AuthFort(
        database_url="sqlite+aiosqlite:///auth.db",
        cookie=CookieConfig(),
    )
    
    @asynccontextmanager
    async def lifespan(app):
        yield
        await auth.dispose()
    
    app = FastAPI(lifespan=lifespan)
    app.include_router(auth.fastapi_router(), prefix="/auth")
    app.include_router(auth.jwks_router())
    
    @app.get("/api/profile")
    async def profile(user=Depends(auth.current_user)):
        return {"email": user.email, "roles": user.roles}
    from contextlib import asynccontextmanager
    from authfort import AuthFort, CookieConfig
    from fastapi import FastAPI, Depends
    
    auth = AuthFort(
        database_url="sqlite+aiosqlite:///auth.db",
        cookie=CookieConfig(),
    )
    
    @asynccontextmanager
    async def lifespan(app):
        yield
        await auth.dispose()
    
    app = FastAPI(lifespan=lifespan)
    app.include_router(auth.fastapi_router(), prefix="/auth")
    app.include_router(auth.jwks_router())
    
    @app.get("/api/profile")
    async def profile(user=Depends(auth.current_user)):
        return {"email": user.email, "roles": user.roles}
  3. Run migrations

    Terminal
    authfort migrate --database-url "sqlite+aiosqlite:///auth.db"
    authfort migrate --database-url "sqlite+aiosqlite:///auth.db"

    This creates the database tables. You only need to run this once (and again after upgrading AuthFort).

  4. Run it

    Terminal
    uvicorn main:app --reload
    uvicorn main:app --reload

That’s it. You now have these endpoints:

MethodEndpointDescription
POST/auth/signupCreate a new user
POST/auth/loginAuthenticate and get tokens
POST/auth/refreshRefresh access token
POST/auth/logoutRevoke refresh token
GET/auth/meGet current user info
GET/.well-known/jwks.jsonPublic signing keys

Open the interactive docs at http://localhost:8000/docs and:

  1. Create a user — POST /auth/signup with {"email": "test@example.com", "password": "mypassword"}
  2. Log in — POST /auth/login with the same credentials
  3. Access profile — GET /api/profile (the cookie is set automatically)
main.py
from authfort import AuthFort, CookieConfig, GoogleProvider, GitHubProvider

auth = AuthFort(
    database_url="sqlite+aiosqlite:///auth.db",
    cookie=CookieConfig(),
    providers=[
        GoogleProvider(client_id="...", client_secret="..."),
        GitHubProvider(client_id="...", client_secret="..."),
    ],
)
from authfort import AuthFort, CookieConfig, GoogleProvider, GitHubProvider

auth = AuthFort(
    database_url="sqlite+aiosqlite:///auth.db",
    cookie=CookieConfig(),
    providers=[
        GoogleProvider(client_id="...", client_secret="..."),
        GitHubProvider(client_id="...", client_secret="..."),
    ],
)

This adds /auth/oauth/google/authorize and /auth/oauth/github/authorize endpoints. See the OAuth guide for setup details.

main.py
@app.get("/api/admin")
async def admin_panel(user=Depends(auth.require_role("admin"))):
    return {"message": "Welcome, admin"}
@app.get("/api/admin")
async def admin_panel(user=Depends(auth.require_role("admin"))):
    return {"message": "Welcome, admin"}

Users without the admin role get a 403 response.

Protect auth endpoints from brute-force attacks:

from authfort import RateLimitConfig
auth = AuthFort(
database_url="sqlite+aiosqlite:///auth.db",
cookie=CookieConfig(),
rate_limit=RateLimitConfig(), # 5/min login, 3/min signup, etc.
)

Exceeding the limit returns 429 with a Retry-After header. See Rate Limiting for details.