Authentication and authorization look simple in tutorials. In production, they’re not. Once you deal with mobile + web clients, third-party login, microservices, token rotation, RBAC, and zero-trust architecture, the picture changes.
This is a practical, system-level breakdown of how authentication, authorization, RBAC, OAuth 2.0, and protected routes actually work in real production systems.
1. Authentication vs Authorization (Clear Separation)
Authentication → Who are you?
Verifying identity.
- Email/password
- OTP
- Social login
- SSO
- Passkeys
Authorization → What can you do?
Determining access level.
- Can user delete invoice?
- Can user access admin panel?
- Can service A call service B?
In production systems, these two concerns must be decoupled.
2. Production-Ready Authentication Architecture
Basic Flow (Email + Password)
- User submits credentials.
- Server validates credentials.
- Server issues tokens.
- Client stores tokens.
- Client sends token with every request.
- Server validates token on each request.
Simple? Yes. But real production includes:
- Password hashing
- Refresh token rotation
- Token expiry
- CSRF protection
- Rate limiting
- Account lockouts
- Audit logs
Password Storage (Never Store Plain Text)
Use:
- bcrypt
- argon2 (preferred modern option)
- scrypt
Flow:
password -> salt -> hash -> store hash only
On login:
input password -> hash with same salt -> compare hash
Never decrypt passwords. You verify them.
3. Token-Based Authentication (JWT in Production)
Most modern systems use JWT (JSON Web Tokens).
A JWT has:
- Header
- Payload
- Signature
Example payload:
{
"sub": "user_id",
"role": "admin",
"iat": 123456,
"exp": 123999
}
How It Works
- User logs in.
- Server signs JWT with private secret.
- Client stores access token.
- Client sends token in:
Authorization: Bearer <token>
- Server verifies signature.
- Server checks expiry.
- Server extracts user identity.
Access Token vs Refresh Token (Critical for Production)
Access Token
- Short lived (5–15 minutes)
- Used in API calls
Refresh Token
- Long lived (7–30 days)
- Stored in HTTP-only secure cookie
- Used to obtain new access token
Refresh Flow
- Access token expires.
- Client calls
/refresh. - Server validates refresh token.
- Server rotates refresh token.
- Server issues new access token.
Rotation prevents replay attacks.
4. OAuth 2.0 (Real Explanation)
OAuth 2.0 is not authentication. It is authorization delegation.
It allows:
“Allow this app to access my Google data.”
Common providers:
- GitHub
OAuth 2.0 Authorization Code Flow (Web App)
Actors:
- Resource Owner (user)
- Client (your app)
- Authorization Server (e.g., Google)
- Resource Server
Flow:
- User clicks "Login with Google"
- Redirect to Google authorization server
- User approves
- Google redirects back with authorization code
- Your backend exchanges code for access token
- Backend fetches user info
- Create or login local user
- Issue your own JWT
Important:
Never trust third-party tokens directly in frontend-only flow for production apps.
PKCE Flow (Mobile + SPA Secure Flow)
PKCE prevents code interception attacks.
Flow adds:
- Code verifier
- Code challenge
Used for:
- SPAs
- Native mobile apps
5. Authorization in Depth
Once authenticated, you must decide:
Can this user perform this action?
There are multiple models:
1. RBAC (Role-Based Access Control)
2. ABAC (Attribute-Based Access Control)
3. PBAC (Policy-Based Access Control)
6. RBAC (Role-Based Access Control)
The most common model.
Core Entities
- User
- Role
- Permission
Example
Roles:
- Admin
- Manager
- User
Permissions:
- create_invoice
- delete_invoice
- view_invoice
Mapping:
User → Role
Role → Permissions
Database Schema (Production Example)
users
roles
permissions
user_roles
role_permissions
Avoid storing roles inside JWT as the only source of truth.
Use token for identity, database for permissions.
RBAC Middleware Flow
- Request hits server
- JWT verified
- User extracted
- Fetch permissions (cached ideally)
- Check required permission
- Allow / Reject
7. Protected Routes (Frontend + Backend)
Backend Protection (Authoritative)
Example middleware logic:
verifyToken()
checkPermission("delete_invoice")
If either fails → 401 or 403.
- 401 → Not authenticated
- 403 → Authenticated but not authorized
Frontend Protected Routes (UX Only)
In React / Next.js:
- Check auth state
- Redirect if not logged in
- Hide admin UI for non-admin
Important:
Frontend protection improves UX.
Backend protection ensures security.
Never rely only on frontend.
8. Session vs JWT (When to Use What)
Session-Based (Server Stored)
- Session ID in cookie
- Server stores session in DB or Redis
Pros:
- Easy invalidation
- More control
Cons:
- Stateful
- Harder to scale without distributed store
JWT (Stateless)
- No server storage needed
- Scales easily
Cons:
- Hard to revoke
- Must implement rotation strategy
Production often uses:
JWT + Redis blacklist
OR
JWT short-lived + refresh rotation
9. Microservices Authentication Flow
In distributed systems:
- API Gateway verifies JWT
- Gateway forwards user context
- Internal services trust gateway
- Zero-trust environments revalidate tokens
Common architecture:
Client → API Gateway → Auth Service
→ User Service
→ Billing Service
Gateway handles:
- Token validation
- Rate limiting
- Logging
- Request tracing
10. Security Best Practices (Non-Negotiable)
Always:
- Use HTTPS
- Use HTTP-only cookies for refresh tokens
- Set SameSite=strict/lax properly
- Implement rate limiting
- Use account lockout after failed attempts
- Enable audit logging
- Use CSRF protection for cookie-based auth
- Rotate signing keys periodically
11. Enterprise-Grade Architecture
In mature systems:
- Dedicated Auth Service
- OAuth 2.0 compliant
- OpenID Connect layer
- Identity provider integration
- SSO support
- MFA support
- Device tracking
- Token introspection endpoint
Popular production identity providers include:
- Auth0
- Okta
- Keycloak
12. Complete Flow Summary (End-to-End)
Login
- User logs in
- Server validates credentials
- Issue access + refresh tokens
- Store refresh token securely
- Return access token
API Call
- Client sends access token
- Server verifies signature
- Extract user ID
- Check permission (RBAC)
- Return response
Token Expired
- Client calls refresh endpoint
- Server validates refresh token
- Rotate token
- Issue new access token
13. What Separates Senior-Level Auth Design
A senior engineer:
- Separates authentication from authorization
- Avoids trusting frontend
- Plans token rotation strategy
- Designs RBAC extensibly
- Considers audit & compliance
- Thinks about key rotation
- Plans migration strategy
- Designs for zero-trust
- Avoids hardcoding roles
- Considers future multi-tenant support
Final Thought
Authentication is not just login.
Authorization is not just admin role.
OAuth is not just social login.
RBAC is not just an enum column.
In production, authentication is architecture.
Top comments (0)