Refresh tokens
Access tokens should expire quickly (like 15 minutes) for safety. A refresh token lasts longer and is used only to get a new access token, so the user doesn't have to log in again. Store the refresh token in an httpOnly cookie so JavaScript can't read it.
// On login: issue both
const accessToken = jwt.sign({ id }, ACCESS_SECRET, { expiresIn: "15m" })
const refreshToken = jwt.sign({ id }, REFRESH_SECRET, { expiresIn: "7d" })
res.cookie("refreshToken", refreshToken, { httpOnly: true, secure: true })
res.json({ accessToken })
// When the access token expires
app.post("/refresh", (req, res) => {
try {
const { id } = jwt.verify(req.cookies.refreshToken, REFRESH_SECRET)
const accessToken = jwt.sign({ id }, ACCESS_SECRET, { expiresIn: "15m" })
res.json({ accessToken })
} catch {
res.status(401).json({ error: "Please log in again" })
}
})