DocumentationSocial sign-in with OAuth and OIDC
API referenceGitHub

Social sign-in with OAuth and OIDC

Generate explicit login and callback routes for Google, GitHub, and LinkedIn.

Work through each step in order. The examples use the generated LenAPI project structure and are designed to be adapted to your app.

01

Set provider credentials in settings

For each enabled provider, set its client ID, client secret, and exact callback URL. Store secrets in environment variables or a local ignored environment file.

Python
GOOGLE_CLIENT_ID = ""
GOOGLE_CLIENT_SECRET = ""
GOOGLE_REDIRECT_URI = ""

GITHUB_CLIENT_ID = ""
GITHUB_CLIENT_SECRET = ""
GITHUB_REDIRECT_URI = ""

SOCIAL_AUTH_ALLOWED_ORIGINS = ["https://myapp.com"]  # Replace with your frontend origin
02

Create and mount the auth router

SocialAuth generates provider login and callback routes only when its router is mounted. The browser starts at a provider login route, the provider authenticates the user, and redirects to the callback. The callback validates state (and PKCE where supported), exchanges the code, fetches the provider profile, and can register/find a local user. With jwt_enabled=True, LenAPI returns its own bearer token for API access; it does not return the provider access token. Use oidc_auth instead when another client already owns login and sends a provider token directly to a protected API route.

Python
from lenapi.security import SocialAuth

auth = SocialAuth(
    providers=["google", "github", "linkedin"],
    auto_register=True,
    jwt_enabled=True,
)

app.include_router(auth.router(), prefix="/auth")
03

Understand what SocialAuth returns

jwt_enabled controls the credential LenAPI issues after the provider callback. In the current implementation, the only built-in LenAPI credential it issues is a JWT access token. It does not issue API keys, session cookies, opaque bearer tokens, or refresh tokens. The provider OAuth access token is used internally to fetch the provider profile and is not returned. With jwt_enabled=False, the callback returns identity and user_id when a local user was resolved, but no LenAPI token.

Python
# With auto_register=True and jwt_enabled=True, the callback response
# has this shape; identity fields depend on the provider:
{
    "identity": {"sub": "provider-subject", "email": "ada@example.com"},
    "user_id": 42,
    "access_token": "<LenAPI JWT>",
    "token_type": "bearer",
    "expires_in": 3600,
}

# Without jwt_enabled=True, the response has identity and, if resolved,
# user_id. It does not contain access_token or token_type.
# Send the LenAPI access token to protected routes as:
# Authorization: Bearer <access_token>
TIP

To issue a session, API key, or opaque token after social login, implement that credential flow explicitly after callback or use a custom callback. Keep provider tokens and LenAPI tokens distinct.

04

Configure provider callback URLs

Register each exact callback URL with the provider console. Google and LinkedIn use OIDC identity endpoints. GitHub uses OAuth 2.0 and its profile/email APIs; it is not an OIDC provider in this integration.

Python
# Example for local development
GOOGLE_REDIRECT_URI = "http://localhost:8009/auth/google/callback"
GITHUB_REDIRECT_URI = "http://localhost:8009/auth/github/callback"
LINKEDIN_REDIRECT_URI = "http://localhost:8009/auth/linkedin/callback"
TIP

X and Facebook are currently disabled; listing either provider does not generate its routes. Microsoft is not currently supported.

05

Run migrations before first sign-in

Automatic registration stores provider subject mappings in a framework-managed table. Verified provider email can be copied to the local user; conflicting email ownership is rejected rather than silently linked.

Python
python lenora.py migration
python lenora.py run