Guide: Adding OAuth¶
Add Google and GitHub OAuth to a FastAuth app. See examples/oauth/.
Prerequisites¶
Register OAuth apps with each provider and copy the client ID and client secret:
- Google — Google Cloud Console → APIs & Services → Credentials → OAuth 2.0 Client ID. Add the Authorized redirect URI
http://localhost:8000/auth/oauth/google/callback. - GitHub — Developer settings → OAuth Apps → New OAuth App. Set the Authorization callback URL to
http://localhost:8000/auth/oauth/github/callback.
Install¶
.env¶
SECRET=... # `fastauth generate-secret`
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
OAUTH_REDIRECT_URL=http://localhost:3000/auth/callback
REDIS_URL=redis://localhost:6379
main.py¶
import os
from contextlib import asynccontextmanager
from dotenv import load_dotenv
from fastapi import FastAPI
from fastauth import FastAuth, FastAuthConfig
from fastauth.adapters.sqlalchemy import SQLAlchemyAdapter
from fastauth.providers.credentials import CredentialsProvider
from fastauth.providers.google import GoogleProvider
from fastauth.providers.github import GitHubProvider
from fastauth.session_backends.redis import RedisSessionBackend
load_dotenv(".env")
adapter = SQLAlchemyAdapter(engine_url="sqlite+aiosqlite:///./auth.db")
config = FastAuthConfig(
secret=os.environ["SECRET"],
providers=[
CredentialsProvider(),
GoogleProvider(client_id=os.environ["GOOGLE_CLIENT_ID"],
client_secret=os.environ["GOOGLE_CLIENT_SECRET"]),
GitHubProvider(client_id=os.environ["GITHUB_CLIENT_ID"],
client_secret=os.environ["GITHUB_CLIENT_SECRET"]),
],
adapter=adapter.user,
token_adapter=adapter.token,
oauth_adapter=adapter.oauth,
oauth_state_store=RedisSessionBackend(url=os.environ["REDIS_URL"],
prefix="fastauth:oauth-state:"),
oauth_redirect_url=os.environ["OAUTH_REDIRECT_URL"],
oauth_allowed_redirect_uris=[
"http://localhost:8000/auth/oauth/google/callback",
"http://localhost:8000/auth/oauth/github/callback",
],
token_delivery="cookie",
base_url="http://localhost:8000",
debug=True, # local only — relaxes Secure cookies on http
)
auth = FastAuth(config)
@asynccontextmanager
async def lifespan(app: FastAPI):
await adapter.create_tables()
yield
app = FastAPI(lifespan=lifespan)
auth.mount(app)
Try the sign-in flow¶
# 1. Get the Google authorization URL
curl "http://localhost:8000/auth/oauth/google/authorize?redirect_uri=http://localhost:8000/auth/oauth/google/callback"
# -> {"url": "https://accounts.google.com/o/oauth2/auth?..."}
# 2. Open the URL in a browser, authorize, you are sent back to /auth/oauth/google/callback.
# FastAuth exchanges the code, creates/links the user, sets the access/refresh/csrf cookies,
# and 302s to oauth_redirect_url (https://app.example.com/auth/callback in prod).
# 3. Hit /auth/me
curl http://localhost:8000/auth/me --cookie "access_token=..."
Account linking¶
Once a user is authenticated, they can link another provider:
# Get an authorization URL to link GitHub (Bearer required)
curl "http://localhost:8000/auth/oauth/github/link?redirect_uri=http://localhost:8000/auth/oauth/github/callback" \
-H "Authorization: Bearer $ACCESS"
# -> {"url": "..."}
# After completing the provider flow, /auth/oauth/github/link/callback completes the link
# (this route is state-bound, no Bearer needed).
# List linked providers
curl http://localhost:8000/auth/oauth/accounts -H "Authorization: Bearer $ACCESS"
# Unlink
curl -X DELETE http://localhost:8000/auth/oauth/accounts/github -H "Authorization: Bearer $ACCESS"
Production notes¶
- Set
oauth_allowed_redirect_uristo your production callback URLs. Removedebug=True. - Use
RedisSessionBackend(or any shared backend), neverMemorySessionBackendwith multiple workers. - Set
base_urlto your public origin. - See OAuth feature for the full endpoint reference.