OIDC login
OIDC login lets Auth redirect a user to an OpenID Connect provider, verify the callback, link the provider identity, and create a Layeron Auth session.
Auth uses the provider discovery document, PKCE S256, a one-time state value, an OIDC nonce, JWKS signature verification, and ID token claim validation.
Configure a Provider
Section titled “Configure a Provider”Add an OIDC provider to the Auth module.
import { auth } from "@layeron/modules"
const appAuth = auth({ providers: [ { provider: "oidc", id: "acme", issuer: "https://idp.example.com", clientId: "client_123", clientSecret: process.env.OIDC_CLIENT_SECRET, redirectToAllowlist: ["https://app.example.com"], }, ],})The provider id is the value used in runtime calls. The issuer must use
HTTPS, and the discovery document issuer value must match the configured
issuer exactly.
The default scopes are openid, email, and profile. Custom scopes must
include openid.
Start Login
Section titled “Start Login”Create the authorization URL from a public route, then redirect the browser to the returned URL.
app.post("/auth/oidc/start", { auth: "public" }, async () => { const result = await appAuth.oauth.createAuthorizationUrl({ provider: "acme", callbackUrl: "https://api.example.com/auth/oidc/callback", redirectTo: "https://app.example.com/dashboard", })
return Response.redirect(result.authorizationUrl, 302)})Auth stores only the state hash, the PKCE verifier, the nonce hash, the callback
URL, and the optional redirectTo value in the Auth state database.
Verify Callback
Section titled “Verify Callback”Pass the provider id, authorization code, and state returned by the provider to Auth.
app.get("/auth/oidc/callback", { auth: "public" }, async ({ request }) => { const url = new URL(request.url) const result = await appAuth.oauth.verifyCallback({ provider: "acme", code: url.searchParams.get("code") ?? "", state: url.searchParams.get("state") ?? "", callbackUrl: "https://api.example.com/auth/oidc/callback", })
return Response.redirect(result.redirectTo ?? "/", 302)})Auth exchanges the code at the provider token endpoint, verifies the ID token
signature with the provider JWKS, checks iss, aud, exp, iat, nbf, and
nonce, then creates a Layeron Auth session.
User Storage Behavior
Section titled “User Storage Behavior”In managed and managed_core mode, Auth creates the user row when the OIDC
identity is first seen. Auth stores emailVerifiedAt only when the provider
sets the configured email verification claim to true.
In custom, mapped, and external mode, Auth uses the configured
userIdClaim as the application user id. The default claim is sub. Your user
resolver or mapped user table must already return a user for that id before
Auth creates the session.
Auth links repeat logins by the configured provider id and the OIDC sub
claim. Auth does not automatically link a new OIDC identity to an existing user
by email address.
Redirect Rules
Section titled “Redirect Rules”redirectTo may be a relative path such as /dashboard. Absolute URLs must use
HTTPS and must match an origin in redirectToAllowlist.
Token Endpoint Authentication
Section titled “Token Endpoint Authentication”When clientSecret is set, Auth uses client_secret_basic by default. Set
tokenEndpointAuthMethod to client_secret_post when the provider requires
the secret in the token request body. Set it to none for public PKCE clients.