Security advanced LIVE DEMO
πŸ”

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...

OAuthPKCEsecuritysingle page appauthenticationauthorization code
Interactive Demo

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

The user browser serves as the execution environment that runs the client application and mediates front-channel redirects with the authorization server. Redirect navigation, user login, and consent steps pass authorization request parameters such as code_challenge and state through the browser interface.

SPA Client

The SPA client is the public browser application that needs delegated access to the user’s protected resources. Before initiating a login request, the client generates a cryptographically random code_verifier, hashes it with SHA-256 to derive the code_challenge, and later exchanges the returned authorization code to store access tokens in memory.

Authorization Server

The authorization server is the trusted security authority that validates user credentials, collects consent, and issues authorization codes and tokens. It records the client’s code_challenge during the initial authorization request and verifies that the submitted code_verifier produces a matching base64url-encoded SHA-256 hash upon code redemption before issuing tokens.

Resource Server

The resource server is the backend API hosting the user’s protected data. It inspects incoming API requests carrying a bearer access token, validates token signature integrity and scopes, and returns the requested profile payload.

Malicious App (Attacker)

The malicious app models an unauthorized actor that intercepts the authorization code on the redirect callback to gain illicit access. When the attacker attempts to exchange the stolen authorization code at the token endpoint without the original code_verifier, the server rejects the request with a 400 Bad Request (invalid_grant) error status.

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.

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.