π PKCE β in plain terms
"Proof Key for Code Exchange" β it stops someone from stealing your login code and using it themselves.
The one-sentence idea
Before you start logging in, your app whispers a secret to itself, sends only a locked box (a hash of that secret) to the login server, and at the very end proves "it was really me" by revealing the original secret. Anyone who intercepts the middle steps can't fake that proof.
Everyday analogy π¨
Imagine ordering a package. You tell the courier a secret word only you know β but you only hand them a sealed envelope containing a scrambled version of it. When the package arrives, you say the secret word out loud; the courier scrambles it the same way and checks it matches the envelope. A porch pirate who grabbed the package still can't say the secret word, so they can't claim it's theirs.
The flow, step by step
sequenceDiagram
autonumber
participant App as π± Your App
participant Auth as π‘οΈ Login Server
participant User as π€ You
Note over App: Make a random secret<br/>code_verifier (kept private)
Note over App: Scramble it β<br/>code_challenge = SHA256(verifier)
App->>Auth: "Start login" + code_challenge (the locked box)
Auth->>User: Show login page
User->>Auth: Enter username / password β
Auth-->>App: Here's a temporary "auth code"
Note over App,Auth: π A thief could steal this auth code here...
App->>Auth: Trade auth code + code_verifier (the real secret)
Note over Auth: Scramble verifier & compare<br/>to the stored challenge
alt Secret matches the box
Auth-->>App: β
Here are your tokens (you're in!)
else Thief has code but NOT the secret
Auth-->>App: β Rejected
end
What each piece is
- code_verifier β a big random secret string your app makes and never shows anyone until the last step.
- code_challenge β the verifier run through
SHA256. Safe to send in the open (you can't un-scramble a hash). - auth code β a short-lived ticket the login server gives back after you sign in.
- the check β at the end, the server re-scrambles your verifier and confirms it equals the challenge it saw at the start.
Why it's safe
The dangerous moment is when the temporary auth code travels back to your app β a thief could grab it. Before PKCE, that stolen code was enough to break in. With PKCE, the code is useless without the verifier, and the verifier never left your device. So a stolen code alone can't complete the login.
Practical rules π
- Always use the
S256method (real SHA256), neverplain. - Make the
code_verifiertruly random and URL-safe (43β128 chars). - Originally for apps with no secret (mobile, single-page, CLI) β now OAuth 2.1 recommends it for everyone.
TL;DR: prove "the app finishing the login is the same app that started it" β without ever sending a reusable secret over the wire.
sharemymd