JWT Authentication
A comprehensive guide to JSON Web Token (JWT) authentication — how stateless authentication works, JWT structure, signing algorithms, token lifecycle, security considerations, refresh tokens, and real-world architecture patterns used in distributed systems.
JWT Authentication
Introduction: The Hotel Key Card Analogy
Imagine checking into a hotel.
At the reception desk:
- You verify your identity.
- The receptionist gives you a key card.
- That key card allows you to:
- Enter your room
- Access elevators
- Use certain hotel services
Important observations:
- The hotel staff doesn't verify your identity every time.
- The key card itself proves your authorization.
- The hotel trusts the encoded information inside the card.
This is exactly how JWT authentication works.
Instead of repeatedly verifying credentials with the server, the system issues a token that proves the user's identity.
What is JWT?
JWT (JSON Web Token) is a compact, URL-safe token used for securely transmitting information between parties.
JWTs are commonly used for:
| Use Case | Description |
|---|---|
| Authentication | Verifying user identity |
| Authorization | Granting access to resources |
| API security | Securing microservice communication |
| Stateless sessions | Replacing server-side sessions |
JWTs are stateless, meaning the server does not need to store session data.
All required information is inside the token.
Stateless vs Stateful Authentication
Before JWTs, systems used session-based authentication.
Session-Based Authentication
Problems:
| Problem | Explanation |
|---|---|
| Session storage | Requires database or cache |
| Scaling difficulty | Sessions must be shared across servers |
| Extra lookups | Every request hits session store |
JWT Authentication (Stateless)
Benefits:
| Benefit | Explanation |
|---|---|
| Stateless | No session storage |
| Fast | No DB lookup |
| Scalable | Works well with microservices |
| Portable | Token can travel between services |
JWT Structure
A JWT has three parts separated by dots:
HEADER.PAYLOAD.SIGNATUREExample JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIn0
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cJWT Components
1 Header
Contains metadata about the token.
Example:
{
"alg": "HS256",
"typ": "JWT"
}Fields:
| Field | Meaning |
|---|---|
| alg | Signing algorithm |
| typ | Token type |
Common algorithms:
| Algorithm | Type |
|---|---|
| HS256 | HMAC SHA256 |
| RS256 | RSA signature |
| ES256 | Elliptic curve |
2 Payload
Contains claims (data) about the user.
Example:
{
"userId": 123,
"role": "admin",
"exp": 1716239022
}Claims fall into three categories.
Registered Claims
Standard fields defined by JWT specification.
| Claim | Meaning |
|---|---|
| iss | Issuer |
| sub | Subject |
| aud | Audience |
| exp | Expiration time |
| iat | Issued at |
| nbf | Not before |
Public Claims
Custom claims defined by developers.
Example:
{
"userId": "abc123",
"plan": "premium"
}Private Claims
Used internally between services.
Example:
{
"permissions": ["read", "write"]
}3 Signature
The signature ensures the token has not been tampered with.
Signature generation:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)Example:
If the payload changes, the signature becomes invalid.
JWT Authentication Flow
Complete login flow:
Authorization Header
JWTs are typically sent using the Authorization header.
Example:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Example JWT Authentication (JavaScript)
Generating JWT
const jwt = require("jsonwebtoken");
const token = jwt.sign(
{ userId: 123, role: "admin" },
"secret_key",
{ expiresIn: "1h" }
);
console.log(token);Verifying JWT
const jwt = require("jsonwebtoken");
function authenticate(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.status(401).send("No token");
}
const token = authHeader.split(" ")[1];
try {
const decoded = jwt.verify(token, "secret_key");
req.user = decoded;
next();
} catch (err) {
res.status(401).send("Invalid token");
}
}Access Token vs Refresh Token
JWT authentication often uses two tokens.
| Token | Purpose |
|---|---|
| Access Token | Used for API calls |
| Refresh Token | Used to obtain new access tokens |
Token Lifecycle
Why Refresh Tokens Exist
Access tokens should be short-lived.
Example:
| Token | Expiration |
|---|---|
| Access Token | 15 minutes |
| Refresh Token | 7 days |
Benefits:
| Benefit | Explanation |
|---|---|
| Security | Limits stolen token damage |
| Usability | Users don't log in repeatedly |
Token Storage Options
Where should JWTs be stored?
Local Storage
localStorage.setItem("token", jwt);Advantages:
- Easy to use
Disadvantages:
- Vulnerable to XSS attacks
HTTP-only Cookies
Safer option.
Set-Cookie: token=jwt; HttpOnlyAdvantages:
| Benefit | Explanation |
|---|---|
| Protected from JavaScript | Prevents XSS access |
| Automatic sending | Browser attaches cookies |
JWT in Microservices
JWT works well in distributed systems.
Instead of each service querying a database, services verify tokens independently.
Each service:
- Verifies JWT signature
- Extracts user identity
- Applies authorization rules
No central session store required.
JWT Security Considerations
JWT misuse can lead to serious security vulnerabilities.
1 Never Store Sensitive Data
JWT payload is not encrypted.
Anyone can decode it.
Bad example:
{
"password": "123456"
}2 Use Short Expiration
Example:
Access token = 15 minutes3 Use HTTPS
Tokens must always travel via HTTPS.
Otherwise they can be intercepted.
4 Rotate Secrets
Secret keys must be rotated periodically.
5 Blacklist Compromised Tokens
For logout functionality:
- Maintain token blacklist
- Or reduce expiration time
JWT vs Session Authentication
| Feature | JWT | Sessions |
|---|---|---|
| Stateless | Yes | No |
| Scalability | High | Medium |
| DB lookup | No | Yes |
| Token size | Larger | Small |
| Revocation | Hard | Easy |
When to Use JWT
JWT is ideal for:
| Scenario | Reason |
|---|---|
| Microservices | Stateless authentication |
| Mobile apps | Token-based access |
| Distributed systems | No session store |
| API authentication | Lightweight verification |
Avoid JWT when:
- Frequent logout needed
- Token revocation required
- Sensitive data involved
Real World Example Architecture
Example: Large-scale application.
Authentication steps:
- User logs in
- AuthService issues JWT
- API Gateway validates token
- Requests forwarded to services
JWT Best Practices
| Practice | Reason |
|---|---|
| Short token expiry | Limits attack window |
| Use refresh tokens | Improves UX |
| Store tokens securely | Prevent XSS |
| Validate signature | Prevent tampering |
| Avoid sensitive payload | Tokens are readable |
Key Takeaways
JWT is one of the most widely used authentication mechanisms in modern systems.
It enables:
- Stateless authentication
- Scalable microservices
- Efficient API security
- Reduced database lookups
However, proper implementation is crucial to avoid security vulnerabilities.
Understanding JWT deeply is essential for designing secure large-scale distributed systems.
