Authentication & Authorization Patterns: JWT, OAuth2, Sessions, and RBAC
Authentication & Authorization: JWT, OAuth2, Sessions, and RBAC#
Auth is the most security-critical part of any system. Get it wrong and you have data breaches, account takeovers, and compliance violations. Get it right and users barely notice it's there.
This guide covers every auth pattern you need — from JWT basics to enterprise SSO.
Authentication vs Authorization#
| Authentication (AuthN) | Authorization (AuthZ) | |
|---|---|---|
| Question | "Who are you?" | "What can you do?" |
| When | Login, token validation | Every protected request |
| Mechanism | Password, OAuth, biometric | RBAC, ABAC, permissions |
| Failure | 401 Unauthorized | 403 Forbidden |
Session-Based Auth#
The traditional approach:
1. User sends credentials → Server validates → Creates session in DB
2. Server returns session ID in Set-Cookie header
3. Browser sends cookie automatically with every request
4. Server looks up session → identifies user
Pros:
- Simple mental model
- Easy to revoke (delete session from DB)
- No token size concerns
Cons:
- Stateful — server must store sessions (Redis/DB)
- Doesn't scale well across multiple servers without shared session store
- Not great for mobile/SPA (cookies are browser-specific)
JWT (JSON Web Tokens)#
Stateless tokens containing user identity:
Header.Payload.Signature
{
"sub": "user_123",
"email": "alice@example.com",
"role": "admin",
"iat": 1711612800,
"exp": 1711616400 // expires in 1 hour
}
Flow:
1. User sends credentials → Server validates → Signs JWT
2. Client stores JWT (memory, not localStorage)
3. Client sends JWT in Authorization: Bearer header
4. Server verifies signature → extracts claims → no DB lookup needed
Pros:
- Stateless — no session store, scales horizontally
- Works across services (microservices can verify independently)
- Contains claims (role, permissions) — no DB lookup per request
Cons:
- Can't revoke individual tokens (until expiry)
- Token size grows with claims
- Must handle refresh token rotation securely
JWT Security Rules#
- Never store in localStorage — XSS can steal it
- Store in httpOnly cookie or in-memory variable
- Short expiry (15 minutes) + refresh token (7 days)
- Use RS256 (asymmetric) over HS256 for microservices
- Validate everything — expiry, issuer, audience, signature
Refresh Token Flow#
Access Token (15 min) — sent with every request
Refresh Token (7 days) — used only to get new access tokens
1. Access token expires → 401 response
2. Client sends refresh token to /auth/refresh
3. Server validates refresh token → issues new access + refresh tokens
4. Old refresh token is revoked (rotation)
Refresh token rotation prevents replay attacks — each refresh token is single-use.
OAuth2 Flows#
OAuth2 lets users sign in with Google, GitHub, etc. without sharing passwords.
Authorization Code Flow (recommended)#
1. App redirects to Google: /authorize?client_id=...&redirect_uri=...
2. User signs in at Google → Google redirects back with code
3. App exchanges code for tokens (server-side, with client_secret)
4. App gets access_token + id_token (user info)
For: Web apps with a backend (most common).
Authorization Code + PKCE#
Same as above but without client_secret. Uses a code_verifier/code_challenge instead.
For: SPAs and mobile apps (no backend to store secrets).
Client Credentials#
App → sends client_id + client_secret → gets access_token
For: Service-to-service auth (no user involved).
Authorization Patterns#
RBAC (Role-Based Access Control)#
Users have roles, roles have permissions:
Admin role → [create, read, update, delete, manage_users]
Editor role → [create, read, update]
Viewer role → [read]
User "Alice" → role: Admin → can do everything
User "Bob" → role: Viewer → can only read
Pros: Simple, easy to audit Cons: Role explosion in complex systems (Admin, SuperAdmin, RegionalAdmin, ...)
ABAC (Attribute-Based Access Control)#
Policies based on attributes of the user, resource, and context:
Policy: Allow if
user.department == resource.department AND
user.clearance_level >= resource.classification AND
request.time is within business_hours
Pros: Fine-grained, context-aware Cons: Complex to implement and debug
ReBAC (Relationship-Based Access Control)#
Authorization based on relationships between entities (Google Zanzibar):
document:readme#viewer@user:alice // Alice can view readme
document:readme#editor@group:team-a // Team A can edit readme
folder:docs#parent@document:readme // readme inherits folder permissions
For: Google Drive, Notion, GitHub — where access depends on object relationships.
Tools: OpenFGA, SpiceDB, Ory Keto
SSO (Single Sign-On)#
One login for all company apps:
User → App A → not authenticated → redirect to IdP (Okta/Auth0)
User → signs in at IdP → redirected back to App A with token
User → App B → not authenticated → redirect to IdP → already signed in!
→ redirected back to App B immediately (no password prompt)
Protocols:
- SAML 2.0 — XML-based, enterprise standard
- OIDC (OpenID Connect) — JSON-based, built on OAuth2, modern standard
SAML vs OIDC#
| SAML | OIDC | |
|---|---|---|
| Format | XML | JSON |
| Token | Assertion | JWT (id_token) |
| Best for | Enterprise legacy | Modern apps |
| Complexity | High | Lower |
Use OIDC unless you have legacy enterprise requirements.
Passwordless Auth#
No passwords at all:
- Magic links — email with login link (valid for 15 min)
- Passkeys (WebAuthn) — biometric/device-based, phishing-resistant
- SMS/Email OTP — one-time code sent to phone/email
Passkeys are the future. Phishing-resistant, no password to steal, built into browsers.
Architecture Examples#
Monolith with Sessions#
Client → Monolith App → Session Store (Redis)
→ PostgreSQL (users table)
Microservices with JWT#
Client → API Gateway → Verify JWT → Extract user claims
→ User Service (issues JWTs)
→ Product Service (trusts JWT claims)
→ Order Service (trusts JWT claims)
→ Auth Service (login, refresh, OAuth)
Enterprise SSO#
Employee → App A → redirect to Okta (SAML/OIDC)
← token + user info
Employee → App B → redirect to Okta (already authenticated)
← token immediately (SSO)
Okta:
→ Universal Directory (users + groups)
→ MFA policies
→ SCIM provisioning to downstream apps
Auth Tools#
| Tool | Type | Best For |
|---|---|---|
| Auth0/Okta | Managed identity | Enterprise SSO, MFA |
| Clerk | Drop-in auth | Next.js, React (fast setup) |
| Supabase Auth | BaaS auth | PostgreSQL-backed, RLS |
| Firebase Auth | BaaS auth | Google ecosystem |
| Keycloak | Self-hosted IdP | Open-source, on-prem |
| NextAuth.js | Auth library | Next.js (DIY approach) |
Summary#
- JWT for stateless APIs — short expiry + refresh rotation
- Sessions for simple web apps — easier revocation
- OAuth2 + PKCE for social login and SPAs
- RBAC for most apps — simple, auditable
- OIDC for SSO — modern standard, JSON-based
- Passkeys are the future — start supporting them now
- Never store tokens in localStorage — httpOnly cookies or in-memory
Audit your auth architecture at codelit.io — OWASP security checks, compliance reports, and vulnerability scans on any diagram.
Try it on Codelit
GitHub Integration
Paste any repo URL to generate an interactive architecture diagram from real code
Related articles
Try these templates
Build this architecture
Generate an interactive architecture for Authentication & Authorization Patterns in seconds.
Try it in Codelit →
Comments