One-liner: Authentication proves who you are; Authorization proves what you're allowed to do. JWT and OAuth 2.0 are the industry standards for doing both at scale.
π« JWT β JSON Web Token
A self-contained, signed token that carries claims about the user. No database lookup needed to verify.
Structure: Header.Payload.Signature
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQyLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MDAwMDB9.abc123sig
HEADER PAYLOAD SIGNATURE
{ { HMACSHA256(
"alg": "HS256", "userId": 42, base64(header) + "." +
"typ": "JWT" "role": "admin", base64(payload),
} "iat": 1699999999, secretKey
"exp": 1700003599 β expires in 1hr )
}
JWT Flow
1. Login: Client βββΊ POST /login {email, password}
Server validates, creates JWT
Client βββ { token: "eyJ..." }
2. Use API: Client βββΊ GET /profile
Headers: Authorization: Bearer eyJ...
Server decodes JWT, checks exp, checks role
Client βββ { user data }
Stateless = Scalable
Server doesn't store sessions. Any server instance can verify the token using the secret key. No Redis/DB lookup needed per request.
JWT Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Token stolen | Short expiry (15min) + Refresh tokens |
| Can't invalidate before expiry | Refresh token blacklist in Redis |
| Payload visible (base64 β encrypted) | Never store sensitive data in payload |
| Weak secret | Use RS256 (asymmetric) for multi-service |
π OAuth 2.0 β Delegated Authorization
OAuth lets a third party app access resources on your behalf, without sharing your password.
"Sign in with Google" is OAuth 2.0 in action.
Authorization Code Flow (Recommended)
User Client App Authorization Server Resource Server
| | (Google/GitHub/etc) (Your API)
|ββ"Login"ββββββΊ|
| |ββRedirectβββΊ|
| | client_id |
|βββββββββββββββ| |
|ββββLogin toβββΊ| |
| Google | |
| |ββauth codeββ|
| | |
| |ββPOST /token|
| | code + |
| | client_secret
| |ββaccess_token + refresh_token
| | |
| |ββGET /userinfo (Bearer access_token)ββββΊ|
| |βββ { id, email, name }ββββββββββββββββββ|
| |
|βββLogged in!ββ|
Key OAuth Concepts
| Term | What It Is |
|---|---|
| Client | Your app |
| Resource Owner | The user |
| Authorization Server | Google, GitHub, Auth0 (issues tokens) |
| Resource Server | API that accepts access tokens |
| Access Token | Short-lived (1hr) β use to call APIs |
| Refresh Token | Long-lived (30 days) β exchange for new access token |
| Scope | Permissions granted: read:email, write:profile
|
π Session vs JWT Comparison
| Session | JWT | |
|---|---|---|
| Storage | Server-side (Redis/DB) | Client-side (localStorage / cookie) |
| Revocation | Instant (delete session) | Must wait for expiry (or blacklist) |
| Scale | Needs shared session store | Stateless β any server works |
| Payload | Just session ID | Full claims (userId, role, etc.) |
| Best for | Monolith, small-medium scale | Microservices, APIs, mobile |
β Pros
JWT: Stateless, scalable, no DB lookup per request, cross-service
OAuth: No password sharing, granular scopes, industry standard for SSO
β Cons
JWT: Revocation is hard, payload visible, long tokens add overhead
OAuth: Complex flow, misconfig is a security disaster, token leakage risks
βοΈ When to Use / When NOT to Use
β JWT β use when:
- REST APIs serving mobile or SPA clients
- Microservices that need to pass identity between services
- Stateless, horizontally scaled backends
β OAuth β use when:
- Third-party "Sign in with X" integrations
- Allowing external apps to access user data on your platform
- Enterprise SSO (Single Sign-On)
β Avoid JWT when:
- You need instant logout / token revocation (use sessions with Redis)
- Highly sensitive systems where payload visibility is a concern
This article was originally published by DEV Community and written by Gouranga Das Samrat.
Read original article on DEV Community