Refresh token

The long-lived credential your app quietly trades for a new access token, so people stay signed in without logging in again.

so users don't get logged outthe thing that renews my loginkeep me signed in tokenrefresh tokkenrenew the access token without asking for the passwordwhy does my session die after an hourstay logged in for 30 dayssilent re-login credential

See it

Live demo coming soon

What it is

A refresh token is a long-lived credential handed out alongside a short-lived access token. Its only job is to be traded back to the authorization server for a fresh access token when the old one expires, with no password, no redirect, and no user interaction. That trade is why a user can close the app on Monday and still be signed in on Friday even though every access token only lived 15 minutes.

The rule that matters: normal renewal sends a refresh token to exactly one place, the token endpoint of your authorization server. It never travels to your product APIs and never appears in an Authorization header on an ordinary request. The one other legitimate destination is the authorization server's revocation endpoint, where you deliberately hand the token over to kill it (RFC 7009). Anywhere else means something is misrouted. Lifetimes range from hours to months, and it is usually opaque (a random string whose hash you store server-side) rather than a JWT, precisely so you can look it up and kill it.

Gotchas: the refresh token is effectively the user's password with a longer reach, so store it where scripts cannot touch it, an HttpOnly + Secure + SameSite cookie in browsers, the Keychain or Keystore on native. localStorage is an XSS payload waiting for a delivery address. Also, when a token expires mid-session, five parallel requests will all get a 401 and all try to refresh at once, so funnel refreshes through a single in-flight promise and replay the queued requests after it resolves.

Ask AI for it

Add refresh token support to this auth flow. On login, issue a 15-minute access token plus an opaque 30-day refresh token, store only a hash of the refresh token server-side with user id, expiry, and device label, and set it as an HttpOnly, Secure, SameSite=Lax cookie scoped to the /auth/refresh path only. Add a POST /auth/refresh endpoint that validates the token, returns a new access token, and 401s on expired or unknown tokens. On the client, wrap the HTTP client in an interceptor that catches a 401, calls refresh through a single shared in-flight promise so parallel requests do not stampede, replays the queued requests, and redirects to login if the refresh itself fails.

You might have meant

access token vs refresh tokenrefresh token rotation and token revocationsilent refreshsession timeoutjwt