OAuth: Redirect & Silent Auth
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
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
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
interface OAuthBuildAuthorizationUrlOptions { /** Redirect URI (must be registered in Admin panel) */ redirectUri: string; /** OAuth scopes */ scopes?: string[]; /** Authentication prompt behavior */ prompt?: 'none' | 'login' | 'consent' | 'select_account'; /** Pre-fill the login hint (e.g., email) */ loginHint?: 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
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
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
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
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
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
Both redirect and silent auth return the same token set:
interface OAuthTokenSet { accessToken: string; idToken?: string; refreshToken?: string; expiresAt: number; // Unix timestamp (seconds) scope?: string;}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
- OAuth: Popup Login — Popup-based authentication
- Cross-Domain SSO — SSO across multiple domains
- Session Management — Managing sessions after OAuth