Authentication Flows
Understand the different OAuth 2.0 flows, when to use them, and how they work with OAuth42.
Overview
OAuth 2.0 defines several authentication flows (also called "grant types") for different use cases. Choosing the right flow depends on your application type, security requirements, and user experience goals.
OAuth42 implements all standard OAuth 2.0 flows and follows current security best practices, including mandatory PKCE for public clients and deprecation of legacy flows.
Authorization Code Flow
Most secure flow for web applications with a backend server that can securely store client secrets.
How It Works
Code Example
// Step 1: Redirect to authorization endpoint
const authUrl = new URL('https://oauth42.com/oauth2/authorize');
authUrl.searchParams.set('client_id', 'your_client_id');
authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/callback');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('scope', 'openid profile email');
authUrl.searchParams.set('state', randomState);
window.location.href = authUrl.toString();
// Step 2: Handle callback on your backend
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
// Verify state to prevent CSRF
if (state !== storedState) {
return res.status(400).send('Invalid state');
}
// Step 3: Exchange code for tokens
const response = await fetch('https://oauth42.com/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
redirect_uri: 'https://yourapp.com/callback',
client_id: 'your_client_id',
client_secret: 'your_client_secret', // Secure on server only!
}),
});
const tokens = await response.json();
// tokens.access_token, tokens.refresh_token, tokens.id_token
});Security Benefits
- •Client secret never exposed to browser
- •Authorization code is single-use and short-lived (10 minutes)
- •Tokens are issued directly to backend server
- •State parameter prevents CSRF attacks
Authorization Code Flow with PKCE
Enhanced security flow for public clients that cannot securely store a client secret.
What is PKCE?
PKCE (Proof Key for Code Exchange, pronounced "pixy") is an extension to the Authorization Code Flow that prevents authorization code interception attacks. It's now mandatory for all public clients in OAuth42.
How PKCE Works
Code Example
// Step 1: Generate PKCE parameters
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64UrlEncode(new Uint8Array(hash));
}
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// Store verifier for later (session storage, not localStorage!)
sessionStorage.setItem('code_verifier', codeVerifier);
// Step 2: Redirect with PKCE parameters
const authUrl = new URL('https://oauth42.com/oauth2/authorize');
authUrl.searchParams.set('client_id', 'your_client_id');
authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/callback');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('scope', 'openid profile email');
authUrl.searchParams.set('code_challenge', codeChallenge);
authUrl.searchParams.set('code_challenge_method', 'S256');
authUrl.searchParams.set('state', randomState);
window.location.href = authUrl.toString();
// Step 3: Exchange code for tokens with verifier
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const codeVerifier = sessionStorage.getItem('code_verifier');
const response = await fetch('https://oauth42.com/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
redirect_uri: 'https://yourapp.com/callback',
client_id: 'your_client_id',
code_verifier: codeVerifier, // No client secret needed!
}),
});
const tokens = await response.json();Why PKCE is Essential
- •Prevents authorization code interception attacks
- •No client secret needed (safe for SPAs and mobile apps)
- •Attacker cannot use stolen code without the verifier
- •Required by OAuth 2.1 specification
Client Credentials Flow
Used when applications need to access their own resources, not user data.
Use Cases
Microservices communicating with each other
Command-line applications accessing APIs
Cron jobs or background tasks
Devices reporting data to backend
Code Example
// Direct token request with client credentials
const response = await fetch('https://oauth42.com/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(`${clientId}:${clientSecret}`),
},
body: new URLSearchParams({
grant_type: 'client_credentials',
scope: 'api:read api:write', // Application-level scopes only
}),
});
const tokens = await response.json();
// tokens.access_token (no refresh token or ID token)
// Use access token for API requests
const apiResponse = await fetch('https://api.yourservice.com/resources', {
headers: {
'Authorization': `Bearer ${tokens.access_token}`,
},
});Important Notes
- ⚠️No user context - tokens represent the application itself
- ⚠️No refresh tokens issued (request new token when expired)
- ⚠️Client secret must be stored securely
- ⚠️Only use for trusted backend services, never in browser or mobile apps
Implicit Flow
This flow has security vulnerabilities and is deprecated in OAuth 2.1. Use Authorization Code Flow with PKCE instead.
Why It's Deprecated
- ✗Access tokens exposed in browser history:Tokens returned in URL fragment can be logged in browser history, proxy logs, and referrer headers
- ✗No refresh tokens:Users must re-authenticate when access token expires
- ✗Vulnerable to token theft:No protection against authorization code interception attacks
Migration Path
If you're currently using Implicit Flow, migrate to Authorization Code Flow with PKCE. It provides better security while maintaining the same user experience. OAuth42 will continue to support Implicit Flow for backward compatibility but strongly recommends migrating.
Resource Owner Password Flow
This flow requires users to share passwords with third-party applications. Only use for highly trusted first-party applications.
Why It's Problematic
- ✗Breaks OAuth security model:User credentials are exposed to the application
- ✗No consent screen:Users cannot review or limit permissions granted
- ✗Phishing risk:Trains users to enter passwords in third-party forms
When It Might Be Acceptable
Only consider this flow for:
- •First-party applications you fully control and trust
- •Migration from legacy authentication systems
- •Environments where browser redirects are not possible
Better alternative: Use Authorization Code Flow with PKCE, even for native mobile apps. Modern OAuth libraries handle this seamlessly.
Flow Comparison
| Flow | Use Case | Security | Refresh Token | Status |
|---|---|---|---|---|
| Authorization Code | Web apps with backend | High | ✓ Yes | ✓ Recommended |
| Authorization Code + PKCE | SPAs, mobile apps | High | ✓ Yes | ✓ Recommended |
| Client Credentials | Machine-to-machine | High | ✗ No | ✓ Recommended |
| Implicit | Legacy SPAs | Low | ✗ No | ⛔ Deprecated |
| Password | First-party apps only | Low | ✓ Yes | ⛔ Deprecated |
Which Flow Should I Use?
Best Practices
Always Use HTTPS
All OAuth 2.0 flows require HTTPS in production. Never use HTTP for authentication flows as credentials and tokens can be intercepted.
Validate State Parameter
Always include and validate the state parameter to prevent CSRF attacks. Generate a random value and verify it matches when handling the callback.
Use Short-Lived Access Tokens
Keep access token lifetime short (15-60 minutes) and use refresh tokens to obtain new ones. This limits the window of opportunity if a token is compromised.
Implement Token Rotation
When using refresh tokens, implement rotation: issue a new refresh token each time one is used. This helps detect token theft and replay attacks.
Secure Client Credentials
Never hardcode client secrets in source code. Use environment variables or secure key management systems. Rotate secrets regularly.
Limit Token Scope
Request only the scopes your application needs. Users are more likely to approve limited permissions, and it reduces risk if tokens are compromised.
Next Steps
Build Your First App
Follow our step-by-step tutorial to implement OAuth42 authentication in your application.
Deep Dive into PKCE
Learn the technical details of PKCE implementation and why it's critical for public clients.
Security Best Practices
Comprehensive guide to securing your OAuth 2.0 implementation against common vulnerabilities.
Authentication API Reference
Detailed API documentation for all OAuth42 authentication endpoints.