OAuth: Redirect & Silent Auth
Overview
Section titled “Overview”The redirect flow navigates the user to the Authrim authorization endpoint for authentication. After completing login, the user is redirected back to your application with an authorization code. This is the standard OAuth 2.0 Authorization Code Flow with PKCE.
Silent authentication checks for an existing IdP session without user interaction, using a hidden iframe.
Both features require enableOAuth: true.
Redirect Flow
Section titled “Redirect Flow”Step 1: Build Authorization URL and Redirect
Section titled “Step 1: Build Authorization URL and Redirect”const auth = await createAuthrim({ issuer: 'https://auth.example.com', clientId: 'my-app', enableOAuth: true,});
const result = await auth.oauth.buildAuthorizationUrl({ redirectUri: 'https://myapp.com/callback', scopes: ['openid', 'profile', 'email'],});
// Redirect to IdPwindow.location.href = result.url;Step 2: Handle Callback
Section titled “Step 2: Handle Callback”In your callback page (/callback):
const auth = await createAuthrim({ issuer: 'https://auth.example.com', clientId: 'my-app', enableOAuth: true,});
const { data, error } = await auth.oauth.handleCallback(window.location.href);
if (error) { console.error('OAuth callback failed:', error.message); return;}
console.log('Access Token:', data.accessToken);console.log('ID Token:', data.idToken);
// Redirect to applicationwindow.location.href = '/dashboard';Authorization URL Options
Section titled “Authorization URL Options”interface OAuthBuildAuthorizationUrlOptions { /** Redirect URI (must be registered in Admin panel) */ redirectUri: string; /** OAuth scopes */ scopes?: string[]; /** Optional state override */ state?: string; /** Optional nonce override */ nonce?: string; /** Authentication prompt behavior */ prompt?: 'none' | 'login' | 'consent' | 'select_account'; /** Pre-fill the login hint (e.g., email) */ loginHint?: string; /** Maximum age of the IdP session in seconds */ maxAge?: number; /** Requested ACR values */ acrValues?: string;}| Prompt Value | Behavior |
|---|---|
none | No UI — fail if not already authenticated (used by silent auth) |
login | Force re-authentication even if session exists |
consent | Force consent screen |
select_account | Show account picker |
Silent Authentication
Section titled “Silent Authentication”Silent auth checks if the user has an active IdP session using a hidden iframe. If the session exists, tokens are returned without user interaction.
Iframe-Based Silent Auth
Section titled “Iframe-Based Silent Auth”const { data, error } = await auth.oauth.silentAuth.check({ redirectUri: 'https://myapp.com/silent-callback', timeoutMs: 5000, // Timeout after 5 seconds (default)});
if (error) { // No active session or silent auth failed console.log('Silent auth failed:', error.message); // Show login button} else { // User is authenticated console.log('Access Token:', data.accessToken);}Silent Auth Flow
Section titled “Silent Auth Flow”sequenceDiagram
participant App as Your App
participant Iframe as Hidden Iframe
participant IdP as Authrim IdP
App->>Iframe: Load auth URL (prompt=none)
Iframe->>IdP: Authorization request
alt IdP has active session
IdP->>Iframe: Redirect with auth code
Iframe->>App: postMessage(code)
App->>IdP: Exchange code for tokens
IdP->>App: Token response
else No session
IdP->>Iframe: Redirect with error=login_required
Iframe->>App: postMessage(error)
App->>App: Show login UI
end
Combining Redirect + Silent Auth
Section titled “Combining Redirect + Silent Auth”A common pattern is to try silent auth first, then fall back to full redirect:
async function authenticate() { // 1. Try silent auth const { data, error } = await auth.oauth.silentAuth.check({ redirectUri: 'https://myapp.com/silent-callback', timeoutMs: 5000, });
if (!error) { // Already authenticated return data; }
// 2. Fall back to redirect const result = await auth.oauth.buildAuthorizationUrl({ redirectUri: 'https://myapp.com/callback', scopes: ['openid', 'profile', 'email'], });
window.location.href = result.url;}Silent Callback Page
Section titled “Silent Callback Page”For iframe-based silent auth, you need a lightweight callback page that only handles the iframe response:
<!DOCTYPE html><html><head><title>Silent Callback</title></head><body> <script src="https://unpkg.com/@authrim/web@latest/dist/authrim-web.umd.global.js"></script> <script> // This page is loaded inside the hidden iframe. // It passes the authorization code back to the parent window. const params = new URLSearchParams(window.location.search); window.parent.postMessage({ type: 'authorization_response', response: Object.fromEntries(params), }, window.location.origin); </script></body></html>Token Response
Section titled “Token Response”Both redirect and silent auth return the same token set:
interface OAuthTokenSet { accessToken: string; idToken?: string; refreshToken?: string; tokenType: 'Bearer' | 'DPoP'; expiresAt: number; // Unix timestamp (seconds) scope?: string;}Error Handling
Section titled “Error Handling”| Error Code | Meaning | Suggested Action |
|---|---|---|
AR005001 | OAuth callback error | Check redirect URI configuration |
AR005002 | Silent auth failed | Fall back to redirect or popup |
AR005003 | No tokens received | Retry or re-authenticate |
const { data, error } = await auth.oauth.silentAuth.check({ redirectUri: 'https://myapp.com/silent-callback',});
if (error) { if (error.error === 'login_required') { // No IdP session — show login button showLoginButton(); } else { // Other error — may want to retry or show error console.error('Silent auth error:', error.message); }}Next Steps
Section titled “Next Steps”- OAuth: Popup Login — Popup-based authentication
- Cross-Domain SSO — SSO across multiple domains
- Session Management — Managing sessions after OAuth