tool / 76

Auth Flows

Walk through every common authentication flow step by step. See the actors, the messages, and how to implement each one.

All local
flows · 12
OAuth 2.0
HTTP
Browser
Transport
OAuth 2.0

Authorization Code + PKCE

The modern default for any client that can't keep a secret — SPAs, mobile apps, CLIs.

when to use
Single-page apps, mobile apps, native desktop apps, and CLIs. Anything where the client cannot securely store a client secret.
used by
Auth0 · Okta · Google Sign-In · GitHub OAuth · Microsoft Identity Platform
spec
RFC 7636 (PKCE), RFC 6749 (OAuth 2.0), draft-ietf-oauth-v2-1
pros
  • PKCE protects against authorization code interception
  • No client secret required
  • Can use refresh tokens
  • Recommended by OAuth 2.1 for all clients
cons
  • Requires a redirect-capable user agent
  • More moving parts than client credentials
sequence· step 1 / 6
User
Client App
Browser
Auth Server
Resource API
step 1 — Generate code verifier & challenge

Client generates a high-entropy random string (the code verifier) and SHA-256 hashes it (the code challenge). The verifier never leaves the client.

request
code_verifier  = base64url(random(32 bytes))
code_challenge = base64url(sha256(code_verifier))
implementation
// Browser (no client secret!)
async function login() {
  const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
  const challenge = base64url(
    new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)))
  );
  sessionStorage.setItem("pkce_verifier", verifier);

  const params = new URLSearchParams({
    response_type: "code",
    client_id: "abc123",
    redirect_uri: window.location.origin + "/callback",
    scope: "openid profile",
    state: crypto.randomUUID(),
    code_challenge: challenge,
    code_challenge_method: "S256",
  });
  window.location.href = "https://auth.example.com/authorize?" + params;
}

// In your /callback route
async function handleCallback() {
  const code = new URLSearchParams(location.search).get("code");
  const verifier = sessionStorage.getItem("pkce_verifier");
  const res = await fetch("https://auth.example.com/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      code: code!,
      redirect_uri: window.location.origin + "/callback",
      client_id: "abc123",
      code_verifier: verifier!,
    }),
  });
  const tokens = await res.json();
  // store securely (httpOnly cookie via your server is safest)
}