πŸ”‘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


  1. Client creates a high-entropy codeverifier and derives a codechallenge (S256).
  2. Authorization request includes challenge and method; the server stores the challenge with the code.
  3. On token exchange the client sends the verifier. The server recomputes and compares. Without the verifier, the stolen code is useless.
  4. 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

Comments (0)

Please log in to leave a comment.

Loading comments...