JWT Deep DiveLesson 2.3
JWT expiry and refresh token strategy
short-lived access tokens, long-lived refresh tokens, refresh token rotation, token family tracking, silent refresh, refresh endpoint implementation
JWT Expiry and Refresh Token Strategy
Short-lived JWTs (15 minutes) limit the damage window if a token is stolen. But forcing users to log in every 15 minutes is unacceptable. Refresh tokens solve this.
The pattern:
- On login, issue two tokens: an access token (15m–1h TTL) and a refresh token (7–30d TTL).
- Store the refresh token in an HttpOnly cookie or server-side.
- When the access token expires, the client hits
POST /auth/refreshwith the refresh token. - Server validates the refresh token, issues a new access token (and optionally a new refresh token — rotation).
// Refresh endpoint
app.post('/auth/refresh', (req, res) => {
const refreshToken = req.cookies.refreshToken;
if (!refreshToken) return res.status(401).json({ error: 'No refresh token' });
try {
const payload = jwt.verify(refreshToken, process.env.REFRESH_SECRET);
const newAccessToken = jwt.sign(
{ sub: payload.sub, role: payload.role },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
res.json({ accessToken: newAccessToken });
} catch {
res.status(401).json({ error: 'Invalid refresh token' });
}
});Refresh token rotation means issuing a new refresh token on every use and invalidating the old one. This limits refresh token theft windows and enables detection of token reuse (a reused old refresh token signals compromise).
