OAuth 2.0 Auth Code Flow with PKCE
Follow the step-by-step OAuth 2.0 Authorization Code Flow with PKCE. Learn how code verifiers and SHA-256 code challenges defend Single Page Applications (SPAs) against authorization code...
Continue with the guided workspace
Use the paired workspace to connect this guide's mental model with live component state, visible signals, and the outcome each step or scenario is meant to prove.
Mental Model
Proof Key for Code Exchange (PKCE, RFC 7636) is an essential security extension to the OAuth 2.0 Authorization Code flow. It secures public clientsβsuch as Single Page Applications (SPAs) and native mobile appsβwhich cannot securely store a static client secret, from authorization code interception attacks.
Components and Why They Exist
User / Browser
Serves as the user environment that executes the client application code and mediates communication with the authorization server. Performs front-channel redirects, user authentication, and consent steps, rendering the UI pages. In the demo, watch how authorization request parameters (such as code_challenge and state) flow via the browser interface.
SPA Client
The public application (running in the userβs browser) that needs delegated access to the userβs protected resources. Generates the cryptographically random code_verifier, hashes it to create the code_challenge, and handles token exchange. In the demo, watch the client generate keys, initiate requests, and store access tokens in memory.
Authorization Server
The trusted security authority that validates user credentials, collects consent, and issues credentials (auth codes, access tokens). Records the clientβs code_challenge during the authorize step, verifies the code_verifier matching during token redemption, and issues tokens. In the demo, watch the authorization server verify the base64url-encoded SHA-256 hash match on code redemption.
Resource Server
The backend API hosting the userβs protected assets/data. Receives API requests containing a bearer access token, validates the token integrity/scopes, and returns resources. In the demo, watch the server accept the validated bearer access token and return profile data.
Malicious App (Attacker)
Models the threat of an unauthorized application intercepting codes to gain illicit access. Attempts to exchange an intercepted authorization code at the token endpoint. In the demo, watch the attackerβs token request fail with a 400 Bad Request (invalid_grant) because they lack the code_verifier.
Edge Cases and Misconceptions
Plain vs. S256 Challenge Methods
The PKCE specification allows two challenge methods: plain and S256. A common pitfall is using plain, where the code_challenge is identical to the raw code_verifier. If an attacker intercepts the initial authorization request, they obtain the plaintext verifier, rendering PKCE useless. Therefore, S256 (SHA-256 hashing) must always be used.
Dynamic Verifiers vs. Static Client Secrets
Confidential server-side clients use static Client Secrets, which are safe because they are kept in secure backend environments. SPAs and mobile apps run code in client environments where static secrets would be exposed. PKCE replaces static secrets with a dynamic, cryptographically strong verifier generated on the fly for every single login request.
PKCE is NOT a replacement for SSL/TLS
A misconception is that PKCE secures the entire communication channel. PKCE specifically prevents authorization code theft at the redirect callback layer (such as custom URL schema interception on mobile OS or browser history logs). It assumes TLS is used to protect back-channel requests to the token endpoint.\n
Common Questions
Why do public clients need PKCE?
Public clients like Single Page Applications (SPAs) and mobile apps run in browser/device environments where Client Secrets cannot be stored securely. PKCE replaces static Client Secrets with dynamic, one-time cryptographic verifiers generated per login.
What is the difference between Code Verifier and Code Challenge?
The Code Verifier is a high-entropy random string generated by the client. The Code Challenge is the SHA-256 hash of the verifier, which is sent during the redirect to register the expectation with the server.
How does PKCE prevent Authorization Code interception?
Even if an attacker intercepts the authorization code, they cannot exchange it for tokens because they do not possess the raw Code Verifier needed to pass the hash match check on the Authorization Server's token endpoint.
Should PKCE be used for confidential server-side clients?
Yes, OAuth 2.1 recommends PKCE for all clients, including confidential server-side applications, as it provides defense-in-depth against code injection attacks.