Introduction
Single Page Applications (SPAs) run entirely in the browser, which makes them fast and user-friendly. However, this also introduces a major security challenge: frontend applications cannot safely store secrets.
This is exactly why PKCE (Proof Key for Code Exchange) exists. PKCE is now the recommended and expected way to implement OAuth 2.0 for public clients such as SPAs.
This article explains what PKCE is, why it is required for frontend OAuth flows, and how it secures authorization in modern web applications.
The Problem with OAuth in the Browser
The original OAuth 2.0 Authorization Code flow was designed for confidential clients, such as backend servers, where a client_secret can be securely stored.
SPAs are public clients:
- Source code is visible to users
- JavaScript executes in untrusted environments
- Any embedded secret can be extracted
Authorization Code Interception
In a browser-based flow, the authorization code is transmitted through redirects. If an attacker intercepts this code, they can exchange it for an access token.
This type of attack is known as authorization code interception, and it is common in:
- Open or compromised networks
- Malicious browser extensions
- Mobile and desktop hybrid apps
Without additional protection, the authorization code can be reused by an attacker.
What Is PKCE?
PKCE (Proof Key for Code Exchange) enhances the Authorization Code flow by adding a cryptographic verification step.
The core idea is simple:
the client that starts the OAuth flow must prove it is the same client that finishes it.
PKCE achieves this without requiring a client secret, making it ideal for SPAs.
How PKCE Works
1. Code Verifier Generation
The SPA generates a high-entropy random string called the code_verifier.
This value is kept private in the browser.
2. Code Challenge Creation
The client hashes the verifier using SHA-256 and encodes it:
code_challenge = BASE64URL(SHA256(code_verifier))
The challenge can be safely sent to the authorization server.
3. Authorization Request
The SPA redirects the user to the authorization server with the challenge:
response_type=code client_id=spa-client redirect_uri=https://app.example.com/callback code_challenge=... code_challenge_method=S256
The authorization server stores the challenge.
4. User Authentication
After the user authenticates and grants consent, the server redirects back with an authorization code.
5. Token Exchange with Proof
The SPA exchanges the authorization code for tokens and includes the original code_verifier.
The authorization server hashes the verifier and compares it with the stored challenge. Tokens are issued only if they match.
Why PKCE Is Essential for SPAs
Without PKCE:
- Authorization codes can be reused
- Intercepted codes can be exchanged for tokens
- Browser-based OAuth flows are vulnerable
With PKCE:
- Authorization codes are bound to the initiating client
- Stolen codes cannot be redeemed
- No client secrets are required
PKCE makes OAuth safe for untrusted environments like browsers.
PKCE Is the Modern OAuth Standard
Current OAuth security best practices require:
- Authorization Code Flow with PKCE for SPAs
- Deprecation of the Implicit Flow
- No client secrets in frontend applications
Major identity providers enforce PKCE for browser-based apps, making it a baseline requirement rather than an optional feature.
Common PKCE Implementation Mistakes
Insecure Storage of the Code Verifier
Avoid long-term storage mechanisms that are vulnerable to cross-site scripting attacks. Prefer in-memory or short-lived session storage.
Using the Plain Challenge Method
Always use the S256 challenge method. The plain method provides weaker security guarantees.
Combining PKCE with Client Secrets
SPAs should not use client secrets at all. PKCE replaces the need for them.
PKCE vs Implicit Flow
Implicit Flow returns tokens directly in the redirect URL, exposing them to browser history, logs, and scripts. PKCE-based Authorization Code flow avoids this by exchanging the code securely and validating the client.
For modern SPAs, PKCE is the correct and secure choice.
Conclusion
PKCE is not an optional enhancement; it is the foundation of secure OAuth 2.0 authentication for frontend applications.
If you are building SPAs, mobile apps, or any public client, Authorization Code Flow with PKCE is the only recommended approach.

