OAuth 2.0 authorization code with PKCE

Authentication and authorization Mid-level Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Order the steps

Order the authorization code + PKCE flow.

  • App redirects the user to /authorize with the challenge and state
  • Server returns access and refresh tokens
  • Server redirects back with a short-lived code
  • App POSTs the code and verifier to /token
  • App creates a random verifier and its SHA-256 challenge

Choose an answer, then open Show answer below to check it.

Show answer

Answer: E A C D B

  1. App creates a random verifier and its SHA-256 challenge The verifier stays in the app.
  2. App redirects the user to /authorize with the challenge and state User signs in at the authorization server.
  3. Server redirects back with a short-lived code App checks state.
  4. App POSTs the code and verifier to /token Server hashes the verifier and compares.
  5. Server returns access and refresh tokens Over the back channel, never in the URL.

30-second answer

The app sends the user to the authorization server with a code challenge (a SHA-256 hash of a random verifier) and gets back a short-lived code on its redirect URI. It then exchanges the code plus the original verifier for tokens over a back channel. An attacker who intercepts the code can't use it without the verifier. The implicit flow, which returned tokens in the URL, is deprecated; current guidance (OAuth 2.1 drafts and the security BCP) is code + PKCE for every client.

Practise saying it · 40 s. No recording, just a timer

Explain code + PKCE.

Say your answer out loud, then check which of these points you covered:

  • Challenge = hash of verifier
  • Code via redirect
  • Exchange code + verifier
  • state against CSRF
  • Implicit is deprecated

Deep dive

Validate the state parameter to stop CSRF on the redirect.

Register exact redirect URIs; no wildcards.

Public clients (mobile, SPA) have no secret; PKCE is what protects them.

OAuth is authorization (access to APIs); OpenID Connect adds authentication (who the user is).

Make a PKCE verifier and S256 challenge Ran on Python 3.13.5 · mypy --strict
Python 3.13
import base64
import hashlib
import secrets

verifier = secrets.token_urlsafe(48)
digest = hashlib.sha256(verifier.encode()).digest()
challenge = base64.urlsafe_b64encode(digest).rstrip(b"=").decode()
print(43 <= len(verifier) <= 128, len(challenge))

Common mistakes

  • Using the implicit flow in new apps.
  • Wildcard redirect URIs.
  • Treating an OAuth access token as proof of the user's identity in your app.

Senior take & follow-ups

Walk the flow, explain verifier/challenge, and say implicit is out.

Follow-up questions

Think of your answer first, then open the hint.

  1. What does PKCE protect against?

    Show hint

    Authorization code interception.

  2. Is OAuth an authentication protocol?

    Show hint

    No; OpenID Connect adds the ID token for that.

Suggest a fix if something here is wrong or out of date.