πKey Takeaway
Why PKCE matters for public clients, code verifier/challenge, state and nonce, token storage, and the flows you must not use in browser/mobile.
OAuth 2.0 PKCE for Browser and Mobile Apps: The Threat-Model-First Setup
Why PKCE matters for public clients, code verifier/challenge, state and nonce, token storage, and the flows you must not use in browser/mobile.
B
Blog-Ghar EditorialAuthor
3 September 2026Published
2 min337 words
12Views
Public clients β browser SPAs and native mobile apps β cannot safely store a client secret. PKCE (RFC 7636) mitigates authorization-code interception by binding the code to a verifier only the legitimate client holds. This guide frames the setup as a threat model, not a copy-paste.
Threat model for public clients
An attacker who can intercept or inject the redirect can try to exchange a stolen code for tokens. On mobile, a malicious app can register the same scheme. On web, a leaked referrer or compromised history can expose the code. Design before you code: where can the code leak, where are tokens stored, and how do you bind the code to the original request?
The PKCE flow, precisely
- Client creates a high-entropy codeverifier and derives a codechallenge (S256).
- Authorization request includes challenge and method; the server stores the challenge with the code.
- On token exchange the client sends the verifier. The server recomputes and compares. Without the verifier, the stolen code is useless.
- Also send state and validate it on return, use exact redirect-URI matching, and add nonce for OpenID Connect id_token.
Implementation that survives review
- Use S256, not plain.
- Generate verifier with a cryptographic RNG (43-128 chars).
- Validate state/nonce and reject if missing or mismatched.
- Exact redirect URI β no wildcard prefix matching on the server.
- Request only the scopes needed; prefer short-lived access tokens and rotating refresh tokens where the provider supports them.
- Do not put tokens in URLs. Keep tokens out of localStorage where possible β prefer memory or secure, httpOnly storage behind your backend, and plan for XSS impact.
What not to do
- Do not use the implicit flow for new apps.
- Do not store a client secret in the app binary or JavaScript bundle.
- Do not accept a code without PKCE on a public client.
Caveats that matter
Provider implementations differ (code lifetimes, refresh rotation, DPoP/binding). Verify the current provider docs and test code-replay, wrong-verifier and state-mismatch cases.
Official source
OAuth.net β PKCE and the authorization server's current documentation. Verify parameter handling before shipping.
Frequently asked question
Q: Does PKCE replace state? No. PKCE binds code to verifier; state binds request to session. Use both.
B
Written by Blog-Ghar Editorial
Passionate about sharing knowledge and insights on technology, lifestyle, and more. Follow for more curated content delivered to your inbox.
1k+ words published
Top contributor