Overview
OAuth 2.0 is an authorization standard enabling secure delegated access. Users authenticate with trusted providers instead of sharing passwords.
Authorization Flows
- Authorization Code: Web applications (most common)
- Implicit: SPAs and browser-based apps
- Client Credentials: Server-to-server communication
- Resource Owner Password: Legacy systems
- Refresh Token: Extend sessions securely
Authorization Code Flow
// 1. Redirect to provider
const authUrl = new URL('https://provider.com/oauth/authorize')
authUrl.searchParams.append('client_id', process.env.OAUTH_CLIENT_ID)
authUrl.searchParams.append('redirect_uri', 'http://localhost:3000/callback')
authUrl.searchParams.append('scope', 'profile email')
authUrl.searchParams.append('response_type', 'code')
response.redirect(authUrl.toString())
// 2. Handle callback
export async function handleCallback(code: string) {
const response = await fetch('https://provider.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: process.env.OAUTH_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET,
redirect_uri: 'http://localhost:3000/callback'
})
})
const { access_token, refresh_token } = await response.json()
return { access_token, refresh_token }
}
// 3. Use access token
const user = await fetch('https://provider.com/oauth/userinfo', {
headers: { Authorization: `Bearer ${access_token}` }
})
Security Best Practices
// Use PKCE for SPAs (Proof Key for Code Exchange)
const codeVerifier = generateRandomString()
const codeChallenge = generateCodeChallenge(codeVerifier)
// Include CSRF token
const state = generateRandomString()
authUrl.searchParams.append('state', state)
// Validate state in callback
if (callbackState !== storedState) {
throw new Error('Invalid state parameter')
}
// Store tokens securely
// ✅ HttpOnly cookies
// ✅ Secure storage with encryption
// ❌ localStorage (vulnerable to XSS)
OAuth 2.0 eliminates the need to store user passwords in your application.