Access tokens should be short-lived. Refresh tokens let clients obtain new access tokens without forcing the user to log in again. This lesson covers a practical Nest refresh-token design.
Access Token + Refresh Token Pair
On login, issue a short-lived access JWT and a longer-lived refresh token. Store a hash of the refresh token server-side (or in a dedicated table). Clients call POST /auth/refresh with the refresh token to receive a new access token (and preferably a rotated refresh token).
Always rotate refresh tokens on use when possible: invalidate the old one and issue a new pair to reduce replay risk.
Safe Refresh Token Storage
// store hashed refresh token
await this.usersService.setRefreshTokenHash(userId, await bcrypt.hash(rawToken, 10));
// verify later
const valid = await bcrypt.compare(rawToken, user.refreshTokenHash);
Never store raw refresh tokens in the database.
Bind refresh tokens to a user (and optionally device/session id).
Provide a logout endpoint that clears the stored refresh hash.
Reject reuse of an already-rotated refresh token (possible theft signal).
Refresh Token Cheatsheet
Practices for Nest refresh-token flows.
Practice
Why
Short access token TTL
Limits damage from leaked bearer tokens
Rotate refresh tokens
Detects token replay/theft
Hash server-side storage
DB leaks do not expose usable tokens
Logout clears hash
Ends the refresh capability immediately
Separate secrets (optional)
Sign access and refresh with different keys
Transporting Refresh Tokens
Browser apps often store refresh tokens in httpOnly Secure cookies while keeping access tokens in memory. Mobile apps use secure device storage. Avoid putting long-lived refresh tokens in localStorage.
Reuse Detection
If a refresh token is presented after it was already rotated, treat it as suspicious: revoke all sessions for that user and force re-login.
Common Mistakes
Making access tokens long-lived and skipping refresh tokens entirely.
Storing refresh tokens in plaintext in the database.
Never invalidating refresh tokens on logout or password change.
Returning refresh tokens in URLs or logs.
Key Takeaways
Refresh tokens extend sessions without long-lived access JWTs.
Hash and rotate refresh tokens; clear them on logout.
Reuse of old refresh tokens should revoke sessions.
Transport choice (cookie vs body) depends on client type and threat model.
Pro Tip
On password change or "log out everywhere", wipe all refresh-token hashes for that user so old devices cannot mint new access tokens.
You now understand refresh tokens. Next, add OAuth social login providers.