OAuth 2.0 Explained Simply — Flows, Tokens, and When to Use Each
OAuth is not authentication#
This is the #1 misconception. OAuth 2.0 is an authorization protocol — it lets apps access resources on behalf of a user. It doesn't verify who the user is.
OpenID Connect (OIDC) is the authentication layer built on top of OAuth 2.0. When someone says "login with Google," they mean OIDC + OAuth together.
The core concept#
Instead of giving an app your password, OAuth lets you grant limited, revocable access through tokens.
Without OAuth:
App asks for your Gmail password → stores it → reads your emails
With OAuth:
App redirects to Google → you approve "read emails" scope
→ Google gives the app a token → app reads emails with that token
→ You can revoke the token anytime
The four roles#
- Resource Owner — You (the user)
- Client — The app requesting access (e.g., a calendar app)
- Authorization Server — Issues tokens (e.g., Google's auth server)
- Resource Server — Hosts the data (e.g., Google Calendar API)
Authorization Code Flow (the most common)#
This is what "Login with Google" uses:
Step 1: Client redirects user to the authorization server
GET https://accounts.google.com/oauth/authorize
?client_id=abc123
&redirect_uri=https://myapp.com/callback
&response_type=code
&scope=email profile
&state=random_csrf_token
Step 2: User logs in and approves the requested scopes
Step 3: Auth server redirects back with an authorization code
https://myapp.com/callback?code=AUTH_CODE_HERE&state=random_csrf_token
Step 4: Client exchanges the code for tokens (server-to-server)
POST https://oauth2.googleapis.com/token
grant_type=authorization_code
&code=AUTH_CODE_HERE
&client_id=abc123
&client_secret=secret456
&redirect_uri=https://myapp.com/callback
Step 5: Auth server returns access token + refresh token
The code-for-token exchange happens server-side, so the access token is never exposed in the browser URL.
PKCE: For mobile and SPAs#
Single-page apps and mobile apps can't keep a client_secret secret. PKCE (Proof Key for Code Exchange) fixes this:
- Client generates a random
code_verifierand a SHA-256 hash (code_challenge) - Sends
code_challengewith the auth request - Sends
code_verifierwhen exchanging the code for tokens - Auth server verifies the hash matches — proves the same client that started the flow is finishing it
Always use PKCE for public clients. It's now recommended for all OAuth flows.
Token types#
Access Token — Short-lived (15 min to 1 hour). Included in API requests as a Bearer token. If stolen, limited damage due to short expiry.
Refresh Token — Long-lived (days to months). Used to get new access tokens without re-authenticating. Store securely — if stolen, attacker gets persistent access.
ID Token (OIDC) — JWT containing user identity claims (name, email, picture). Only used for authentication, not API access.
Other flows#
| Flow | Use case |
|---|---|
| Authorization Code + PKCE | Web apps, mobile apps, SPAs |
| Client Credentials | Server-to-server (no user involved) |
| Device Code | Smart TVs, CLI tools (no browser) |
| Implicit | Deprecated — use Auth Code + PKCE instead |
| Password Grant | Deprecated — never send passwords to third-party apps |
Common security mistakes#
Not validating the state parameter. This prevents CSRF attacks. Always generate a random state, store it in the session, and verify it on callback.
Storing tokens in localStorage. Vulnerable to XSS. Use httpOnly cookies for refresh tokens, and keep access tokens in memory.
Not rotating refresh tokens. Use refresh token rotation — each time a refresh token is used, issue a new one and invalidate the old one.
Overly broad scopes. Request the minimum scopes needed. read:email not admin:everything.
Not checking token audience. Verify the access token was issued for your API, not someone else's.
Visualize your auth architecture#
See how OAuth flows connect your app, auth server, and resource servers — try Codelit to generate an interactive diagram of your authentication system.
Key takeaways#
- OAuth = authorization, OIDC = authentication
- Authorization Code + PKCE is the standard flow for all clients
- Access tokens are short-lived, refresh tokens are long-lived
- Never store tokens in localStorage — use httpOnly cookies
- Always validate
stateto prevent CSRF - Implicit and Password grants are deprecated — don't use them
Try it on Codelit
Chaos Mode
Simulate node failures and watch cascading impact across your architecture
Related articles
Batch API Endpoints — Patterns for Bulk Operations, Partial Success, and Idempotency
8 min read
system designCircuit Breaker Implementation — State Machine, Failure Counting, Fallbacks, and Resilience4j
7 min read
testingAPI Contract Testing with Pact — Consumer-Driven Contracts for Microservices
8 min read
Try these templates
OpenAI API Request Pipeline
7-stage pipeline from API call to token generation, handling millions of requests per minute.
8 componentsDistributed Rate Limiter
API rate limiting with sliding window, token bucket, and per-user quotas.
7 componentsAuthentication & Authorization System
OAuth2/OIDC-based auth with SSO, MFA, session management, and role-based access control.
8 componentsBuild this architecture
Generate an interactive architecture for OAuth 2.0 Explained Simply in seconds.
Try it in Codelit →
Comments