Protocols and how-tos
How to implement the OpenID Connect authorization code flow
A practical walkthrough of OpenID Connect sign-in: discovery, the authorization request, the code exchange, and the ID token checks that are not optional.
The short answer
To add OpenID Connect sign-in, register a client and redirect URI with the provider, redirect the user to the provider's authorization endpoint with response_type=code, a PKCE challenge, state and nonce, then exchange the returned code at the token endpoint from your server. Validate the ID token's signature, issuer, audience, expiry and nonce before trusting any claim in it, and only then create your own application session.
Sources last reviewed .
Before you write code
Fetch the provider's discovery document at /.well-known/openid-configuration (OpenID Connect Discovery 1.0). It lists the authorization, token, userinfo and JWKS endpoints, the supported scopes and the signing algorithms. Hard-coding endpoints you could have discovered is how integrations break on a provider migration.
Register exact redirect URIs. RFC 9700 requires exact string matching for redirect URIs; wildcard or prefix matching is how authorization codes end up delivered to an attacker's page.
The flow
- Create state, nonce and a PKCE code verifier. Store all three against the user's pre-login session.
- Redirect to the authorization endpoint with client_id, redirect_uri, response_type=code, scope=openid (plus profile or email if you need them), state, nonce, code_challenge and code_challenge_method=S256.
- The user authenticates at the provider. Your application never sees the password.
- On the callback, reject the request unless state matches what you stored. Then exchange the code, redirect_uri and code_verifier at the token endpoint, authenticating the client if it is confidential.
- Validate the ID token (next section). Only then read its claims.
- Create your own session — a new session identifier, not one that existed before login — and discard the stored state, nonce and verifier.
ID token validation is the whole point
OpenID Connect Core section 3.1.3.7 lists the checks. At minimum: the signature verifies against a key from the provider's JWKS with an algorithm you expect (never alg=none, never an algorithm chosen by the token itself); iss equals the provider's issuer exactly; aud contains your client_id; exp is in the future; nonce equals the value you sent. RFC 8725 adds the general JWT rules — pin the algorithms you accept and do not let the token's header select the verification key type.
Skipping validation because the token came over TLS from the token endpoint is a defensible shortcut in a narrow case the specification allows, but it is fragile: the day the token is passed to another component, the unverified assumption travels with it.
Your session is separate from the provider's
After sign-in there are two sessions: the provider's and your application's. Signing out of one does not end the other unless you implement logout for both — RP-initiated logout to end the provider session, and back-channel or front-channel logout if the provider needs to end yours.
In Authreads
How this applies to Authreads
Authreads hosted login is an OpenID Connect provider with a discovery document, a JWKS endpoint publishing Ed25519 verification keys, authorization code with mandatory S256 PKCE, refresh token rotation, token revocation and RP-initiated logout. The developer portal documents the exact endpoints and claims.
Authreads is a multi-tenant identity platform in beta. Capability status is maintained on /roadmap as Available, In progress or Planned.
Keep reading
Protocols and how-tos
PKCE explained: how it protects the authorization code
Protocols and how-tos
How to validate a JWT access token in your API
Protocols and how-tos
Logout in OpenID Connect: RP-initiated, front-channel and back-channel
Glossary: OpenID Connect (OIDC) · Authorization code flow · ID token · JWKS · PKCE
Building on any of this?
Tell us what you're putting together. We'll tell you plainly whether Authreads fits it.