Imagine a user logs into your application.
The authentication server generates a JWT.
Client
↓
Login
↓
JWT Issued
↓
Subsequent API RequestsEverything works perfectly...
Until one day the user's access token gets stolen.
Maybe their laptop was compromised.
Maybe an XSS attack leaked the token.
Maybe someone copied it from browser storage.
Now the attacker can send requests using the exact same JWT.
The first question most interviewers ask is:
"How do you revoke the token?"
The tricky part is that JWTs are stateless.
Once a JWT is issued, the server doesn't normally store it anywhere.
Every request is simply verified using the secret key.
String username = jwtService.extractUsername(token);
if(jwtService.isTokenValid(token)){
// Allow request
}The server never checks a database.
So if an attacker steals the JWT, it remains valid until it expires.
Why Not Store Every JWT?
Imagine millions of active users.
Storing every access token would defeat one of JWT's biggest advantages.
Without JWT
↓
Database Lookup
↓
Validate Session
↓
Process RequestInstead, JWT verification is extremely fast.
Verify Signature
↓
Extract Claims
↓
Accept RequestNo database required.
That's why JWTs scale so well.
But it also means immediate revocation isn't built in.
Solution 1: Short Lived Access Tokens
This is the most common solution.
Instead of issuing a token valid for several hours, issue one that expires quickly.
Access Token
Expires In
10 MinutesEven if an attacker steals it, the damage is limited.
Solution 2: Refresh Tokens
Instead of forcing users to log in every ten minutes, applications also issue a refresh token.
Login
↓
Access Token
(10 mins)
+
Refresh Token
(30 days)When the access token expires:
Client
↓
Refresh Token
↓
New Access TokenThe user stays logged in without entering their password again.
Solution 3: Revoke The Refresh Token
Suppose the user reports suspicious activity.
Simply delete the refresh token.
DELETE
FROM refresh_tokens
WHERE user_id = 101;Now the attacker cannot obtain new access tokens.
Existing access tokens eventually expire.
Solution 4: Token Blacklisting
Sometimes waiting ten minutes is unacceptable.
For example:
- Banking
- Healthcare
- Enterprise applications
A common solution is Redis.
Redis
↓
Blacklisted JWT IDsWhenever a request arrives:
if(redis.exists(jwtId)){
throw new UnauthorizedException();
}Now compromised tokens can be revoked immediately.
The downside is that every request now requires an additional Redis lookup.
Solution 5: Refresh Token Rotation
A more secure approach is rotating refresh tokens.
Login
↓
Refresh Token A
↓
Exchange
↓
Refresh Token BThe old refresh token becomes invalid immediately.
If someone later attempts to use Token A again:
Token Reuse Detected
↓
Possible Token Theft
↓
Terminate SessionMany modern authentication providers use this strategy.
Solution 6: Token Versioning
This is one of my favorite interview answers because it's simple and elegant.
Each user stores a token version.
Users Table
id
token_version
1When generating a JWT:
{
"userId":101,
"version":1
}Every request compares the JWT version against the database.
if(jwt.version != user.tokenVersion){
rejectRequest();
}Need to log the user out from every device?
Simply increment the version.
UPDATE users
SET token_version = token_version + 1
WHERE id = 101;Every existing JWT immediately becomes invalid.
No blacklist required.
Additional Security Layers
Large applications often combine multiple techniques.
- Device fingerprinting
- Risk based authentication
- IP reputation checks
- Location anomaly detection
- Multi Factor Authentication (MFA)
Even if a valid JWT is presented, suspicious activity can trigger additional verification.
What Interviewers Want To Hear
If an interviewer asks:
"JWTs are stateless. How do you revoke them?"
A strong answer is:
JWTs are stateless by design, so immediate revocation requires introducing some server side state. In practice, I would use short lived access tokens with revocable refresh tokens. For highly sensitive applications, I'd also maintain a Redis blacklist or implement token versioning to invalidate existing sessions immediately.
Final Thoughts
JWTs are excellent for scalability because they eliminate database lookups for every request.
But that convenience comes with a tradeoff.
Once issued, a JWT cannot magically disappear.
The best authentication systems don't rely on a single technique.
They combine short lived access tokens, refresh token rotation, revocation mechanisms, and server side validation to balance both performance and security.
That's the difference between simply using JWTs and designing an authentication system that's ready for production.