Modern web applications need authentication systems that are secure, scalable, and stateless. One widely used approach is JWT (JSON Web Token)–based authentication combined with Access Tokens, Refresh Tokens, and Redis for session control and enhanced security.
This article explains how the system works, why it is designed this way, and how to implement it.
- What is JWT?
A JWT (JSON Web Token) is a compact, URL-safe token used to transmit information securely between parties.
A JWT has three parts:
Header
Payload
Signature
Example structure:
xxxxx.yyyyy.zzzzz
Header: Contains algorithm and token type
Payload: Contains user data (claims)
Signature: Ensures token integrity
The server signs the token, and the client sends it in requests.
The Problem with Simple JWT Authentication
A basic JWT system issues one token that lasts for hours or days.
Problems:
If the token is stolen, it can be used until expiration
No easy way to revoke tokens
Long expiry increases security risk
To solve this, modern systems use Access Tokens + Refresh Tokens.Access Token vs Refresh Token
Feature Access Token Refresh Token
Lifetime Short (5–15 min) Long (days or weeks)
Usage Access APIs Generate new access tokens
Stored In Memory / HTTP-only cookie Secure storage (DB or Redis)
Risk Lower Higher (must be protected)Authentication Flow (Conceptual Diagram)
User Login
│
▼
Server verifies credentials
│
├── Access Token (short life)
└── Refresh Token (long life, stored in Redis)
│
▼
Client uses Access Token for API requests
│
▼
Access Token expires
│
▼
Client sends Refresh Token
│
▼
Server verifies token in Redis
│
▼
New Access Token issuedWhy Redis is Used
Redis is an in-memory data store that is extremely fast.
Redis helps in:
Storing Refresh Tokens securely
Blacklisting revoked tokens
Managing session expiry
Detecting token reuse attacks
Without Redis, refresh tokens stored only on the client cannot be easily revoked.Token Storage Strategy
Best practice:
Access Token:
Stored in memory or HTTP-only cookie
Short expiration
Refresh Token:
Stored in HTTP-only cookie
Stored in Redis on server side
Redis example structure:
Key: refreshToken:userId
Value: token
TTL: 7 days
- Implementation Example (Node.js + Express) Install dependencies npm install jsonwebtoken redis cookie-parser Generating Tokens const jwt = require("jsonwebtoken");
function generateAccessToken(user) {
return jwt.sign(user, process.env.ACCESS_SECRET, { expiresIn: "15m" });
}
function generateRefreshToken(user) {
return jwt.sign(user, process.env.REFRESH_SECRET, { expiresIn: "7d" });
}
Storing Refresh Token in Redis
await redisClient.set(
refreshToken:${user.id},
refreshToken,
{ EX: 604800 } // 7 days
);
Refresh Token Endpoint
app.post("/refresh", async (req, res) => {
const token = req.cookies.refreshToken;
if (!token) return res.sendStatus(401);
const storedToken = await redisClient.get(refreshToken:${userId});
if (storedToken !== token) return res.sendStatus(403);
jwt.verify(token, process.env.REFRESH_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
const accessToken = generateAccessToken({ id: user.id });
res.json({ accessToken });
});
});
- Security Best Practices
Use HTTPS to prevent token interception
Use HTTP-only cookies to prevent XSS attacks
Rotate refresh tokens after each use
Set short expiry for access tokens
Store refresh tokens in Redis with expiration
Optional advanced protection:
Token fingerprinting
IP/device binding
Refresh token rotation with blacklist
Advantages of This Approach
Stateless API authentication
Fast token verification
Easy scaling in microservices
Centralized session control using Redis
Better protection against token theftReal-World Usage
This pattern is used in:
Banking dashboards
SaaS products
Mobile apps with APIs
Large-scale distributed systems
Conclusion
JWT authentication becomes significantly more secure when combined with short-lived access tokens, refresh tokens, and Redis for session management. This approach balances performance, scalability, and security while keeping APIs stateless.
Top comments (0)