🔒 PKCE Implementation Guide
PKCE (Proof Key for Code Exchange) is required for all OAuth flows with Earth Miles. This guide shows you how to implement it correctly.
What is PKCE?
PKCE enhances OAuth security by preventing authorization code interception attacks. It works by:
- Generating a random
code_verifier
- Creating a
code_challenge
by hashing the verifier - Sending the challenge with the authorization request
- Sending the original verifier with the token exchange
Implementation Steps
1. Generate Code Verifier
Create a cryptographically random string of 43-128 characters:
2. Create Code Challenge
Hash the verifier with SHA-256 and Base64URL encode it:
Full Example
import base64
import hashlib
import secrets
import urllib.parse
def generate_code_verifier():
"""Generate a random code verifier."""
return base64.urlsafe_b64encode(secrets.token_bytes(32)).decode('utf-8').rstrip('=')
def generate_code_challenge(code_verifier):
"""Generate code challenge from verifier."""
digest = hashlib.sha256(code_verifier.encode('utf-8')).digest()
return base64.urlsafe_b64encode(digest).decode('utf-8').rstrip('=')
# Example usage
code_verifier = generate_code_verifier()
code_challenge = generate_code_challenge(code_verifier)
# Build authorization URL
params = {
'client_id': 'your_client_id',
'redirect_uri': 'https://your-app.com/callback',
'scope': 'miles:read miles:write',
'state': secrets.token_urlsafe(16),
'response_type': 'code',
'code_challenge': code_challenge,
'code_challenge_method': 'S256'
}
auth_url = f"https://backend.earthmiles.app/oauth/authorize?{urllib.parse.urlencode(params)}"
const crypto = require('crypto');
function generateCodeVerifier() {
return crypto.randomBytes(32).toString('base64url');
}
function generateCodeChallenge(codeVerifier) {
return crypto.createHash('sha256').update(codeVerifier).digest('base64url');
}
// Example usage
const codeVerifier = generateCodeVerifier();
const codeChallenge = generateCodeChallenge(codeVerifier);
console.log('Code Verifier:', codeVerifier);
console.log('Code Challenge:', codeChallenge);
Security Best Practices
- Generate truly random verifiers using cryptographically secure random number generators
- Store code verifiers securely - preferably server-side, never in client-side storage (avoid localStorage or cookies)
- Use the verifier only once - generate new PKCE parameters for each authorization flow
- Validate parameters - ensure code challenge matches the verifier during token exchange
- Implement proper error handling for PKCE validation failures