PKCE (Proof Key for Code Exchange)
An OAuth 2.0 extension that secures the authorization code flow for public clients without requiring client secrets.
What is PKCE (Proof Key for Code Exchange)?
PKCE (Proof Key for Code Exchange) is an OAuth 2.0 extension (RFC 7636) that secures the authorization code flow for public clients that cannot securely store client secrets.
Public clients include:
- Mobile apps: iOS, Android apps (can be decompiled)
- SPAs (Single Page Apps): JavaScript apps running in browsers
- Native desktop apps: Electron, Flutter, React Native apps
Without PKCE, the authorization code flow is vulnerable to authorization code interception attacks. PKCE solves this by having the client create a code verifier (random string) and send a code challenge (hash of verifier) with the authorization request. Only the client that knows the verifier can exchange the code for tokens.
Analogy
Think of PKCE like a secret handshake combined with a temporary password. Even if someone intercepts your 'handshake' (authorization code), they can't use it without the 'secret' (code verifier) that only your app knows.
Types and Use Cases
- Mobile Apps: Secure OAuth flows on iOS/Android without client secrets
- SPAs: Secure JavaScript apps running in browsers
- Native Desktop Apps: Electron, Flutter apps without secure secret storage
- IoT Devices: Devices that cannot protect client secrets
How it Works
// Step 1: Generate Code Verifier and Challenge
function generatePKCE() {
const codeVerifier = generateRandomString(128); // e.g., "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
// Create code challenge (S256 = SHA-256 base64url)
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const hash = await crypto.subtle.digest('SHA-256', data);
const codeChallenge = base64urlEncode(hash);
return { codeVerifier, codeChallenge };
}
// Step 2: Authorization Request (with PKCE)
GET /oauth/authorize?
client_id=1234567890&
response_type=code&
code_challenge=K2LBjD...base64urlencoded_hash...&
code_challenge_method=S256&
redirect_uri=https://app.example.com/callback
// Step 3: Token Exchange (with Verifier)
POST /oauth/token
grant_type=authorization_code&
code=auth_code_from_redirect&
code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk&
redirect_uri=https://app.example.com/callbackPKCE (Proof Key for Code Exchange) vs Traditional Authorization Code Flow (without PKCE)
PKCE (Proof Key for Code Exchange)
Traditional Authorization Code Flow (without PKCE)
PKCE requires code_verifier (known only to client)
Traditional flow relies on client_secret (which public clients can't protect)
PKCE protects against authorization code interception
Traditional flow is vulnerable for mobile/SPAs
PKCE is mandatory in OAuth 2.1 for all clients
Traditional flow is deprecated for public clients
Best Practices for PKCE (Proof Key for Code Exchange)
- Always use PKCE for SPAs and mobile apps (mandatory in OAuth 2.1)
- Use S256 method: Always use SHA-256 (S256) for code challenge, not plain (P1K1)
- Generate strong verifiers: Use cryptographically secure random strings (minimum 43 characters)
How LoginRadius Powers PKCE (Proof Key for Code Exchange)
LoginRadius CIAM platform provides full PKCE support for secure authentication in SPAs, mobile apps, and native applications. Our iOS, Android, and JavaScript SDKs automatically implement PKCE (S256 method) for the authorization code flow. LoginRadius allows you to enforce PKCE for all OAuth clients, supports OAuth 2.1 requirements, and provides detailed PKCE flow logs for debugging and compliance.
FAQs
No, PKCE is designed for public clients (mobile apps, SPAs) that cannot securely store client secrets. Confidential clients (server-side web apps) can still use the traditional authorization code flow with client_secret. However, OAuth 2.1 recommends PKCE for ALL clients (even confidential ones) as an extra layer of security.
S256 uses SHA-256 hash of the code_verifier as the challenge (secure - even if challenge is intercepted, verifier can't be derived). plain uses the code_verifier itself as the challenge (insecure - if challenge is intercepted, attacker knows the verifier). Always use S256 - never use plain.
LoginRadius fully supports PKCE for secure mobile and SPA authentication: (1) PKCE enforcement - optionally require PKCE for all OAuth flows, (2) S256 support - we support SHA-256 code challenges, (3) Mobile SDKs - our iOS/Android SDKs automatically implement PKCE, (4) SPA SDK - our JavaScript SDK handles PKCE for browser-based apps, (5) OAuth 2.1 ready - our platform is ready for OAuth 2.1 requirements.