Explain Codes LogoExplain Codes Logo

Invalidating JSON Web Tokens

javascript
token-invalidation
jwt-security
access-refresh-token
Nikita BarsukovbyNikita Barsukov·Nov 22, 2024
TLDR

Invalidate a JWT instantly by binding it with a unique identifier (jti) and cross-verify this against a server-side blacklist every request.

// Necessities const jwt = require('jsonwebtoken'); const redis = require('redis'); let blacklist = redis.createClient(); // Dumbledore's Wand, the token. const token = jwt.sign({ user_id: user.id, jti: uuidv4() }, secret, { expiresIn: '1h' }); // Avada Kedavra! The token is no more blacklist.set(token.jti, true); // Till the ashes (token expiration) blacklist.expireat(token.jti, Math.floor(Date.now() / 1000) + 3600);

Check the blacklist:

// Our very own polygraph test function isTokenRevoked(token) { const { jti } = jwt.verify(token, secret); return blacklist.get(jti) != null; } // Middleware. Not the one you're thinking! 😉 app.use((req, res, next) => { const token = req.headers.authorization.split(' ')[1]; if (isTokenRevoked(token)) res.status(403).json({ message: 'Token invalidated' }); else next(); });

The jti claim is leveraged here to map a token to its blacklist entry swiftly.

Understanding JWT invalidation (No magic included)

JSON Web Tokens (JWT) are used to authenticate requests, conceived to be stateless. It means that they don't themselves have an 'off-switch'!

In general, a token is valid until it's expired. So, how do you invalidated a token which is yet to expire? Here come several strategies to cater to that.

Living on the edge: Token Lifecycle

Short-lived tokens act as a safety precaution. Reducing their lifespan decreases the damage window if a token is compromised.

Opt for an access-refresh token pattern. You get short-lived access tokens, complemented by longer-lived refresh tokens. When the access token expires, Refresh! It's a minibreak from constant re-authentication.

Employ token versioning. Add a version number in your JWT payload, and increase this whenever a user logs out. Voila, invalidated token!

Red Button Strategy: System-wide invalidation

When things hit the fan, go nuclear! Change the key used to sign the tokens (the JWT Secret). It invalidates all existing tokens instantly. But use this sparingly. It's like Spiderman without his mask, revealing the identity isn't always good!

Reinforcing the Fort: Refresh tokens

Refresh tokens, though long-lived, need protection too. If stored insecurely and compromised, they could be used to gain prolonged unauthorized access. Maintain a separate blacklist for refresh tokens. Check them only when a refresh request is kicked.

Invisible Man Handover

Move the refresh process server-side! All the hustle of token exchange happens behind the scenes, invisible to the client. Reduced exposure, increased security.

Multi-player mode: Multi-channel session

Handling users active on multiple devices means supporting multiple refresh tokens per user, each tagged with a unique identifier. Logout doesn't feel like a death sentence when you only invalidate the token from the logged-out device.

Security with Redis

Rely on redis! It's an efficient stooge to hold your token blacklists. Whether it's to check if a token is revoked or to expire a token, Redis has got you covered.