Plain OAuth2 login¶
GitHub-style login: providers that speak OAuth2 but not OIDC — no discovery document, no signed id_token. Full app: examples/oauth2/main.py, including the GitHub profile mapper quoted below.
from fastauth.config import FastAuthConfig, OAuth2Config, OAuth2ProviderConfig
from fastauth.core import OAuth2Auth
from fastauth.types import OAuthUserInfo
async def map_github_profile(profile: dict) -> OAuthUserInfo:
return OAuthUserInfo(
provider="github",
provider_user_id=str(profile["id"]),
email=profile.get("email"),
email_verified=True,
name=profile.get("name") or profile.get("login"),
avatar_url=profile.get("avatar_url"),
)
oauth2 = OAuth2Auth(
adapter=SQLAlchemySessionAdapter,
user_model=User,
session_model=Session, # strategy="session" needs this
db_session_dependency=get_db,
oauth_account_model=OAuth2Account, # FastAuthOAuthAccountMixin + unique (provider, provider_user_id)
strategy="session",
config=FastAuthConfig(
oauth2=OAuth2Config(
secret_key="<openssl rand -hex 32>",
providers=[
OAuth2ProviderConfig(
name="github",
client_id=...,
client_secret=...,
redirect_uri="http://localhost:8000/auth/oauth2/github/callback",
authorization_url="https://github.com/login/oauth/authorize",
token_url="https://github.com/login/oauth/access_token",
userinfo_url="https://api.github.com/user",
scopes=["read:user", "user:email"],
map_profile_to_user=map_github_profile, # async; may call APIs
)
],
)
),
)
How it works¶
Same shape as OIDC: GET /auth/oauth2/{provider}/login → provider → GET /auth/oauth2/{provider}/callback. Differences:
- No discovery —
authorization_url,token_url,userinfo_urlare configured explicitly. - No verified identity token — your async
map_profile_to_userconverts the raw profile JSON toOAuthUserInfo(it can make follow-up API calls, e.g. GitHub's separate emails endpoint). on_after_oauth2_loginobservers receive anOAuth2LoginResultcarrying the provider's own access/refresh token. FastAuth never persists those tokens — the hook decides what to do with them.
Same fail-closed account rules as OIDC (no email takeover, inactive → 403, orphaned rows → 401). Full signatures: OAuth2Auth and OAuth2Provider.