Prompt
How do I store refresh tokens safely?
Latest observation
Oct 6, 2026
OpenAI APIWeb search: off
Safely storing refresh tokens is mostly about preventing theft and limiting damage if they’re stolen.
Best practices
1) Prefer not storing them in the browser if you can avoid it
- Best option for web apps: keep refresh tokens server-side.
- Use the browser only for short-lived access tokens or a session cookie.
2) If you must store them in a browser, use a Secure, HttpOnly, SameSite cookie
Set the refresh token in a cookie with:
- HttpOnly: JavaScript can’t read it
- Secure: sent only over HTTPS
- SameSite=Lax or Strict: helps reduce CSRF risk
Example cookie attributes:
Set-Cookie: refresh_token=...; HttpOnly; Secure; SameSite=Lax; Path=/auth/refresh
3) Never store refresh tokens in:
- localStorage
- sessionStorage
- plain browser memory if it can be avoided for long-lived tokens
- logs, URLs, or analytics events
Why: anything readable by JavaScript is vulnerable to XSS token theft.
4) Use refresh token rotation
- Every time a refresh token is used, issue a new refresh token
- Invalidate the old one immediately
- Detect reuse of an old token and revoke the whole session if possible
This greatly reduces the impact of token theft.
5) Store them encrypted at rest on the server
If you keep refresh tokens in a database:
- encrypt them at rest
- restrict access tightly
- consider storing only a hashed token or a hashed token identifier if your architecture allows it
6) Tie tokens to a session/device context
Common protections:
- store a session ID alongside the token
- track user agent/device metadata carefully
- revoke tokens on password change, logout, or suspicious activity
Be careful not to rely too heavily on device fingerprinting; it’s brittle.
7) Use short-lived access tokens
Refresh tokens exist because access tokens should be short-lived. Typical pattern:
- Access token: minutes
- Refresh token: days/weeks, with rotation
8) Provide revocation and logout
You should be able to:
- revoke one token
- revoke all tokens for a user
- expire tokens after inactivity or absolute lifetime
Recommended setups by app type
Web app
- Refresh token in HttpOnly Secure SameSite cookie
- Access token in memory or also via server session
- Rotate refresh tokens
Mobile app
- Store refresh token in Keychain (iOS) / Keystore (Android)
- Never in plain app storage
Backend/service-to-service
- Store secrets in a secret manager or encrypted config store
- Rotate frequently and scope narrowly
Quick rule of thumb
If someone steals your refresh token, they can usually keep minting new access tokens. So:
- don’t expose it to JavaScript
- rotate it
- encrypt/store it safely
- be able to revoke it
If you want, I can also give you:
- a recommended architecture for a web app, or
- concrete examples for Node/Express, Next.js, or Django.