OAuth 2.0 and OpenID Connect: delegated authentication done right
OAuth 2.0 flows, authorization code flow, PKCE, state parameter, implicit flow risks, access tokens vs ID tokens, token validation, third-party library use
OAuth 2.0 and OIDC
OAuth 2.0 is an authorization framework that lets users grant third-party applications limited access to their accounts without sharing passwords. OpenID Connect (OIDC) adds identity on top of OAuth—the ID token is the proof of who the user is.
Use the Authorization Code Flow with PKCE
The implicit flow (which returns tokens directly in the URL fragment) is deprecated. It exposes tokens in browser history and server logs. Always use the authorization code flow with PKCE for public clients (SPAs, mobile apps).
PKCE Prevents Authorization Code Interception
const crypto = require('crypto');
// Step 1: Generate a code verifier and challenge
const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256')
.update(verifier).digest('base64url');
// Store verifier in session, send challenge in auth request URL
// ?code_challenge=CHALLENGE&code_challenge_method=S256
// Step 2: Token exchange — include verifier
const tokens = await fetch(tokenEndpoint, {
method: 'POST',
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authCode,
code_verifier: verifier // Server verifies hash matches challenge
})
});The State Parameter
Always include a random state parameter in the authorization request and verify it when the callback returns. This prevents CSRF attacks on the OAuth callback endpoint itself.
// Generate and store state
const state = crypto.randomBytes(16).toString('hex');
req.session.oauthState = state;
// In callback — verify before proceeding
if (req.query.state !== req.session.oauthState) {
return res.status(400).json({ error: 'State mismatch — possible CSRF' });
}