When to use interactive login
Use this pattern when you need:- A user to authenticate directly through PymtHouse’s login UI.
- An ID token or access token tied to the authenticated user session.
- RP-initiated logout (RFC 6749, OIDC Core) to return users to your app after sign-out.
Prerequisites
- A registered public OIDC client (
app_…) withauthorization_codegrant enabled. - A registered
redirect_urifor your application. - For public clients: PKCE is required.
- For confidential server-side clients: client secret is required at the token endpoint.
{issuer}/.well-known/openid-configuration rather than hard-coding paths.
The authorization code flow
Step 1 — Redirect to the authorization endpoint
Construct the authorization URL with the required parameters and redirect the user’s browser.| Parameter | Value |
|---|---|
code_verifier | Cryptographically random string, 43–128 chars, URL-safe characters. Store in session. |
code_challenge | BASE64URL(SHA256(ASCII(code_verifier))) |
code_challenge_method | S256 |
state parameter: Generate a random, opaque value per authorization request and store it in the user’s session. Verify it exactly on the callback to prevent CSRF attacks (RFC 6749 §10.12).
Scopes. Request only scopes registered on the client. Common values:
| Scope | Purpose |
|---|---|
openid | Required to receive an ID token. |
profile | Basic identity claims. |
email | Email address claim. |
Example: generate PKCE in Node.js
Step 2 — Handle the callback
PymtHouse redirects the user agent back to yourredirect_uri with a short-lived authorization code and the state value you sent.
- Verify
statematches the value you stored in the session. Reject if not. - Verify no
errorparameter is present. Surface theerror_descriptionto your logging system if present.
Step 3 — Exchange the code for tokens
client_secret to the body (or use HTTP Basic auth with client_id:client_secret — RFC 7617). Do not send code_verifier if you are using a confidential client without PKCE.
Successful response:
Token validation
Validate theid_token before creating a user session:
- Verify the signature using the JWKS published at
{issuer}/jwks. - Verify
issmatches your configured issuer URL. - Verify
audcontains yourclient_id. - Verify
exphas not passed. - Verify
nonce(if you sent one in the authorization request) to prevent token replay.
openid-client for Node.js) handle this automatically when you pass the issuer and client id during initialization.
Refresh tokens
Refresh tokens (pmth_rt_…) allow your app to obtain new access tokens without re-authenticating the user. Exchange a refresh token at the token endpoint:
RP-initiated logout
When a user signs out of your app, also terminate the PymtHouse session. Use theend_session_endpoint from discovery:
post_logout_redirect_uri must be pre-registered on the client.
Error handling
error value | Meaning | Action |
|---|---|---|
access_denied | User denied consent. | Show a friendly message; do not retry automatically. |
invalid_request | Malformed authorization request. | Log the error_description; fix the client-side parameter. |
invalid_grant | Code already used, expired, or redirect_uri mismatch. | Restart the authorization flow. |
unauthorized_client | The client is not authorized for this grant type. | Check client registration; contact the platform admin. |
Key design decisions
- PKCE is mandatory for public clients. Without PKCE, authorization codes intercepted by a malicious app or redirect-hijack could be exchanged for tokens by an attacker. RFC 7636 closes this by binding the code to a secret the attacker cannot know.
stateprevents CSRF. A missing or incorrectly validatedstateparameter has historically been the most common CSRF vector in OAuth implementations (RFC 6749 §10.12). Treat validation as non-negotiable.end_session_endpointfor single sign-out. Closing only your local session while leaving the OP session open allows another tab or app to silently re-authenticate the user. RP-initiated logout ensures the OP session terminates alongside your app session.
Implementation tasks
- Use an established OIDC client library (e.g.,
openid-client,next-auth, Passport.jsopenid-connect) rather than implementing the flow manually. Libraries handle signature verification, PKCE, and token validation correctly by default. - Register every
redirect_uriyour app uses — including localhost for development — in the client configuration. Unregistered URIs are rejected by the token endpoint withinvalid_grant. - Store the
code_verifierin a server-side session or a secure,HttpOnlycookie, never in the URL orlocalStorage. - Implement the full
stateround-trip: generate before redirect, verify on callback, invalidate after single use. - Enable refresh-token rotation and revoke refresh tokens on explicit logout to limit the impact of token theft.