🔐OAuth 2.0 Flows Explained
Understand every OAuth 2.0 flow — auth code, PKCE, client credentials, device — by name, by purpose, and by threat model, then ship a minimal client you can defend on a security review.
Phase 1The Roles, Tokens, and Trust Boundaries
Decode OAuth roles, tokens, and why redirects exist
OAuth is about delegation, not authentication
6 minOAuth solves 'let this app do something on my behalf' — not 'prove who I am.' Confusing the two is the root of most OAuth bugs.
Four roles, one dance
6 minEvery OAuth flow is the same four actors passing messages: resource owner, client, authorization server, resource server.
Access tokens are bearer tickets — treat them that way
7 minWhoever holds an access token can use it. There's no cryptographic binding to the user, the device, or the client by default.
The redirect URI is the whole security model
7 minThe redirect URI is how the authorization server decides where to send the user and the code — which means it's also how attackers try to steal them.
Phase 2Walking The Authorization Code + PKCE Flow
Walk the authorization code and PKCE flow step by step
The auth request is a URL — read it like one
7 minThe initial authorization request is nothing more than a GET to the authorization server with specific query params. If you can read URLs, you can read OAuth.
Consent is the only step the user sees
6 minThe consent screen is where the user grants delegation — it's the product UX of OAuth, and scopes are its vocabulary.
The code is single-use, short-lived, and worthless alone
7 minAn authorization code is a bearer ticket with a ten-minute shelf life that must be redeemed by the same client that requested it.
PKCE replaces the client secret with proof of origin
8 minPKCE is a tiny hash trick that makes the authorization code flow safe for apps that can't keep a secret.
The token response is the whole prize
7 minOne JSON blob contains everything the client needs: the access token, the refresh token, the expiry, and the actually-granted scope.
Phase 3Choosing The Right Flow For The Job
Compare implicit, client credentials, and device flows on tradeoffs
Your SPA just got a token in its URL. What do you do?
8 minYour SPA just got a token in its URL. What do you do?
Your service needs to call another service. No user in sight.
7 minYour service needs to call another service. No user in sight.
Your CLI can't open a browser. Now what?
7 minYour CLI can't open a browser. Now what?
Your refresh tokens aren't rotating. Silent data-breach time bomb.
8 minYour refresh tokens aren't rotating. Silent data-breach time bomb.
Phase 4Ship A Minimal OAuth Client
Implement a minimal OAuth client against a real provider
Build a minimal OAuth client against a real provider
25 minBuild a minimal OAuth client against a real provider
Frequently asked questions
- What's the difference between OAuth 2.0 and OpenID Connect?
- This is covered in the “OAuth 2.0 Flows Explained” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- Why is the implicit flow considered deprecated for new apps?
- This is covered in the “OAuth 2.0 Flows Explained” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- When should I use PKCE instead of a client secret?
- This is covered in the “OAuth 2.0 Flows Explained” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- What's the actual risk if I skip the 'state' parameter?
- This is covered in the “OAuth 2.0 Flows Explained” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- Why does the device flow exist when auth code already works?
- This is covered in the “OAuth 2.0 Flows Explained” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
Related paths
🐍Python Decorators Introduction
Build one mental model for Python decorators that covers closures, argument passing, functools.wraps, and stacking — then ship a working caching or logging decorator from scratch in under 30 lines.
🦀Rust Lifetimes Explained
Stop reading `'a` as line noise and start reading it as scope arithmetic — one failing snippet at a time — until you can thread lifetimes through a small parser or iterator adapter without fighting the borrow checker.
☸️Kubernetes Core Concepts
Stop drowning in 30+ resource types. Build the mental model one primitive at a time -- pods, deployments, services, ingress, config -- then deploy a real app with rolling updates and health checks.
📈Big O Intuition
Stop treating Big O as math you memorized for an interview — build the intuition to spot O(n²) disasters, pick the right data structure without thinking, and rewrite a slow function from O(n²) to O(n) in under five minutes.