100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Refresh Tokens

Refresh tokens let a client obtain new access tokens without forcing the resource owner to re-authenticate, and how they're issued and rotated is central to OAuth 2.0 security.

Tokens & ScopesIntermediate9 min readJul 10, 2026
Analogies

Why Refresh Tokens Exist

Access tokens are deliberately short-lived, often expiring in 5 to 60 minutes, to limit the damage a leaked token can cause. Forcing the resource owner to log in again every time an access token expires would be unusable, so the authorization server issues a longer-lived refresh token alongside the access token during the initial grant. The client stores the refresh token and, when the access token expires, silently exchanges it at the token endpoint for a fresh access token, without any browser redirect or user interaction, keeping the session alive while still bounding the blast radius of any single access token.

🏏

Cricket analogy: It's like a player's central contract with the BCCI: the match-day accreditation (access token) needs renewing every series, but the underlying contract (refresh token) means Rohit Sharma doesn't have to reapply for a new career every time one accreditation expires.

Refresh Token Rotation

In modern OAuth 2.0 deployments, especially for public clients like single-page apps and mobile apps, the authorization server rotates the refresh token on every use: each call to the token endpoint returns both a new access token and a new refresh token, and the old refresh token is immediately invalidated. This turns a stolen refresh token into a detectable event, since if both the legitimate client and an attacker ever try to use the same refresh token after one of them has already redeemed it, the second attempt fails, signaling token theft. Best practice ties this to automatic reuse detection: if a rotated-out refresh token is ever presented again, the authorization server should revoke the entire token family, not just the one request.

🏏

Cricket analogy: It's like a one-time toss coin used only once per match at the Eden Gardens: reusing yesterday's toss coin today immediately tips off the umpire that something's wrong, just as reusing an old refresh token flags theft.

http
POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=v1.MzQ4YTk3ZjEtNGQ3YS05YzNlLTJmOGI1YTFlMGQ3Nw
&client_id=spa-web-client

// Response: both tokens rotate
HTTP/1.1 200 OK
Content-Type: application/json

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "v1.OTFiNC00ZDdhLTljM2UtMmY4YjVhMWUwZDc4",
  "token_type": "Bearer",
  "expires_in": 900
}
// The previous refresh_token is now invalid; reusing it
// triggers reuse detection and revokes the token family.

Storage and Lifetime Considerations

Because a refresh token typically lives far longer than an access token, sometimes days or months, its storage location matters far more. Confidential clients running on a server can keep refresh tokens in a secure backend data store, but public clients like SPAs and native apps should combine rotation with sender-constraining techniques, or fall back to the Backend-for-Frontend pattern, keeping refresh tokens out of JavaScript-accessible storage entirely. Absolute and idle lifetimes should both be enforced: an absolute lifetime forces re-authentication after a fixed ceiling regardless of activity, while an idle lifetime expires a refresh token if it hasn't been used recently, limiting how long a stolen-but-unused token remains dangerous.

🏏

Cricket analogy: It's like the difference between a season-long stadium pass kept in a locked club safe (confidential client backend storage) versus a paper pass a fan carries loose in a pocket at the ground (SPA storage), which is far easier to lose or have pickpocketed.

Never store a long-lived refresh token in localStorage or a JavaScript-readable cookie for a browser-based app — any XSS vulnerability anywhere on the page grants an attacker a durable credential, not just a momentary one. Prefer HttpOnly, Secure, SameSite cookies managed by a backend-for-frontend.

  • Refresh tokens let clients get new access tokens without redirecting the user back through login, keeping sessions alive while access tokens stay short-lived.
  • Rotation issues a new refresh token on every use and invalidates the previous one, turning theft into a detectable, observable event.
  • Reuse of an already-rotated refresh token should trigger revocation of the entire token family, not just rejection of that one request.
  • Public clients (SPAs, native apps) need extra protection for refresh tokens: sender-constraining, rotation, or a Backend-for-Frontend pattern.
  • Both absolute lifetimes (hard ceiling) and idle lifetimes (expiry after inactivity) should be enforced on refresh tokens.
  • Refresh tokens should never live in localStorage or JS-readable cookies in a browser context, due to XSS exposure risk.
  • Confidential clients can store refresh tokens server-side in a protected data store, which is inherently safer than any browser-accessible storage.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#OAuth20StudyNotes#RefreshTokens#Refresh#Tokens#Exist#Token#StudyNotes#SkillVeris#ExamPrep