What is a refresh token and why use it alongside a short-lived access token?
The access token is short-lived (minutes) and sent on every request. The refresh token is long-lived, stored safely and used only to get a new access token. A stolen access token then expires quickly, and refresh tokens can be revoked.
Explain it simply
A visitor pass at an office gate is valid for one day, and you show it at every door. Your permanent employee card stays in a locked drawer and is used only at the reception desk to print a fresh pass. If someone steals the day pass, it dies by evening. The employee card is rarely exposed.
Flow:
- Login returns a 15-minute access token and a 7-day refresh token.
- Every API call carries the access token.
- When the API answers 401 (expired), the client sends the refresh token to
/auth/refresh. - The server checks the refresh token against its store, then issues a new access token (and ideally a new refresh token).
- Logout deletes the refresh token on the server.
Example
app.post("/auth/refresh", async (req, res) => {
const old = req.cookies.refresh_token;
const record = old && (await RefreshToken.findOne({ token: hash(old) }));
if (!record || record.expiresAt < new Date()) {
return res.status(401).json({ error: "Please log in again" });
}
await record.deleteOne(); // rotation: one use only
const next = await issueRefreshToken(record.userId);
const access = jwt.sign({ sub: record.userId }, process.env.JWT_SECRET, { expiresIn: "15m" });
res.cookie("refresh_token", next, { httpOnly: true, secure: true, sameSite: "strict" });
res.json({ access });
});Store only a hash of refresh tokens in the database, so a database leak does not hand out valid tokens. Rotation (a new refresh token on each use) lets you detect reuse of a stolen one.
What to say in the interview
"Short access tokens limit damage if stolen; a stored, revocable refresh token gets new ones without asking for the password again. I rotate refresh tokens, store them hashed and keep them in an httpOnly cookie."
Common mistakes
- Making the access token last for days and calling it done.
- Storing refresh tokens in plain text in the database.