MODULE 3/LESSON 2
🔴 Redis Architecture

Session Store & JWT Blacklisting

Centralized session store and JWT blacklisting with Redis

10 min
In a microservices architecture, services must be stateless to scale horizontally. If a user logs into Server A, but their next request hits Server B, Server B needs to know they are authenticated. Redis solves this by providing a blazing-fast centralized session store.

Key Concepts

Centralized Sessions

Instead of storing sessions in Server Memory (stateful), store them in Redis. Any microservice can fetch `session:xyz` from Redis in <1ms.

JWT Limitations

JSON Web Tokens (JWTs) are stateless, which is great! But you cannot revoke a JWT before it expires if a user clicks 'Log Out' or gets banned.

JWT Blacklisting

To revoke a JWT, you store the token's ID (jti) in a Redis Set (`SADD blacklist <jti>`) with an expiration time equal to the token's remaining TTL. API Gateways check this Redis Set before allowing requests.

Rolling Expiration

Redis makes it easy to implement 'Rolling Sessions'. Every time a user makes a request, you simply call `EXPIRE session:xyz 3600` to extend their session by another hour.

Stateless Microservices Architecture

Stateless Microservices with Centralized Auth API Gateway / Load Balancer Order Service Payment Service User Service Redis Cluster Centralized Session Store / JWT Blacklist HGET session:1001 | SISMEMBER blacklist:token123

How JWT Blacklisting Works (Technical Details)

auth.service.tstypescript
1// 1. When a user logs out, we get their JWT's 'jti' (JWT ID) and 'exp' (Expiration Time)
2const decodedToken = jwt.decode(token);
3const jti = decodedToken.jti;
4const exp = decodedToken.exp;
5
6// 2. Calculate remaining time until the token naturally expires
7const now = Math.floor(Date.now() / 1000);
8const timeRemaining = exp - now;
9
10// 3. Add to Redis Blacklist, but ONLY for the time remaining!
11// This is crucial to prevent Redis from running out of memory.
12if (timeRemaining > 0) {
13  // SETEX: Set value and Expiration
14  await redis.setex(`blacklist:${jti}`, timeRemaining, 'revoked');
15}
16
17// 4. In your Auth Middleware (API Gateway)
18const isBlacklisted = await redis.exists(`blacklist:${jti}`);
19if (isBlacklisted) {
20  throw new UnauthorizedException('Token has been revoked');
21}

Comparing Approaches

ApproachState LocationProsCons
Stateful (Sticky Sessions)Server RAMSimple to implementCannot scale easily, load balancer becomes a bottleneck
Stateless (Pure JWT)Client (Browser)Zero database lookups, scales infinitelyCannot revoke tokens, cannot force logout
Stateless (Redis Session)RedisCentralized, easy to manage and revokeRequires Redis infrastructure, slight latency overhead
Hybrid (JWT + Redis Blacklist)Client + RedisFastest lookups, strictly revocableSlightly complex to manage JWT lifetimes and Blacklist sync
💡
Senior Architect Insight: In a hybrid JWT + Blacklist architecture, you only need to query Redis if the JWT signature is valid. This prevents malicious actors from spamming your Redis instance with randomly generated tokens, because the API Gateway drops invalid tokens before they ever reach the Blacklist check.