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)
}