The auth microservice
Your company has five backend services. Three of them need to authenticate users. Instead of reimplementing auth in each, you build one auth service that issues tokens. Everyone else just verifies the signature.
Solution A is the classic stateless JWT. The auth service issues a signed token with the user id and role. Other services verify the signature with a shared secret or public key. There is no revocation and no refresh. Tokens expire after their exp claim.
Solution B adds refresh tokens and a revocation list. Access tokens live for 15 minutes. Refresh tokens live for weeks and are stored in the auth database. When a user logs out or you detect a stolen token, you revoke the refresh token and the attacker can no longer get new access tokens. More moving parts, more safety.
app.post('/login', async (req, res) => {
const user = await validateCredentials(req.body);
const accessToken = jwt.sign(
{ userId: user.id, role: user.role },
JWT_SECRET,
{ expiresIn: '15m' },
);
const refreshToken = crypto.randomBytes(32).toString('hex');
await db.refreshTokens.insert({
token: hash(refreshToken),
userId: user.id,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
});
res.json({ accessToken, refreshToken });
});Issue an access token and a refresh token. Store the refresh token in the database.
The tradeoff to defend. Solution A is stateless all the way through. Any service can verify a token without asking the auth service for anything. But you cannot revoke a stolen token until it expires. Solution B adds a database round trip for refresh but gives you real revocation. Pick solution A for internal systems with trusted clients. Pick solution B for anything facing real users.
Quiz: Quiz
Loading practice…