Card 03/ 11
The Authorization Code Flow With PKCE
The browser carries a short code, and only the app that started the flow can exchange it for a token.
In the authorization code flow, the client sends the user to the authorization server, the user signs in and consents, and the server sends the browser back with a short-lived code, never a token. The client then exchanges the code for tokens directly with the server. PKCE, Proof Key for Code Exchange, makes the exchange work only for the client that started the flow. Here the photo printing app reads a user's photos. Values are illustrative and shortened.
The code flow with PKCE, step by step
The client makes a verifier and its challenge
The app generates a random code verifier and keeps it private. It computes the code challenge, the SHA-256 hash of the verifier encoded as base64url.
The client sends the user to the authorization server
The browser is redirected to /authorize with the client id, the requested scope, a redirect URI registered in advance, a random state value, and the code challenge.
The user signs in and consents
The authorization server shows its own login page, then a consent screen listing what the app asks for. The app never sees the password.
The server redirects back with a code
The browser is sent to the app's redirect URI with a one-time code and the same state, which the app checks to know the response belongs to its request.
The client exchanges the code and the verifier
The app posts the code and the original verifier to /token. The server hashes the verifier, compares it with the challenge it stored, and only then returns the access token and usually a refresh token.
The client calls the API
The app sends the access token in Authorization: Bearer on each request to the photo API.
Why a code, not a token. The redirect passes through the browser, its history and possibly a malicious extension. A code seen there is useless on its own, because the exchange happens directly between the app and the server.
What PKCE stops. Without it, an attacker who intercepted the code, for example through another app registered for the same redirect on a phone, could exchange it. With PKCE, the exchange also needs the verifier, which never left the app.
For every client. PKCE was designed for mobile apps, and current guidance in RFC 9700 asks for it from every client, including server-side ones that also have a secret.
← → move through sections and cards