Illustration of a sailing ship symbolizing steady progress
← Back to blog

Token lifecycle

Token Refresh 101: How OAuth Refresh Tokens Actually Work

Learn why refresh tokens exist, how the rotation pattern works, and what to watch for when tokens stop working.

Paulina XuNovember 22, 20257 min
OAuthTokensArchitecture

Why Refresh Tokens Exist

Access tokens are intentionally short-lived (often 5–60 minutes) to limit damage if they leak. But re-authenticating users every hour is not practical. Refresh tokens let your backend obtain a fresh access token behind the scenes so automations keep running.

The Refresh Flow

  1. Request offline access. During the OAuth consent flow, request the offline_access scope (or equivalent). This signals that your integration needs long-lived access.
  2. Provider returns access and refresh tokens. After exchanging the authorization code, the response typically includes access_token, refresh_token, expires_in, and token_type fields.
  3. Store the refresh token securely. Refresh tokens never belong in the frontend. Keep them in encrypted server storage or a secrets manager.
  4. Exchange the refresh token when the access token expires. POST grant_type=refresh_token along with your client credentials. The provider returns a fresh access token and, sometimes, a new refresh token.
  5. Continue calling APIs without user interaction. The new access token lets you resume API calls seamlessly. Users stay signed in while your backend manages token lifecycles.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
refresh_token=REFRESH_TOKEN

Refresh Token Rotation

Providers such as Google, Slack, and Auth0 often issue a new refresh token every time the old one is used. Adopt rotation whenever it is supported.

  • Reduces the impact of token theft by invalidating the previous refresh token automatically.
  • Makes it easier to detect abuse when the same token shows up from multiple IPs or devices.
  • Lets providers revoke a single refresh token context without disconnecting the entire app.

When Refresh Tokens Stop Working

An invalid_grant response usually means the refresh token is no longer valid. Here are the most common causes:

  • The user revoked your app in their account settings.
  • The provider detected suspicious activity such as an unusual location or device.
  • The workspace or organization disabled your application.
  • The user changed their password or policy triggers forced re-consent.
  • Your app mis-handled rotation and tried to reuse an already rotated token.

When a refresh token fails, prompt the user to re-authorize. Avoid silent loops that hammer the provider with repeated refresh attempts.

Security Best Practices

  • Treat refresh tokens like passwords: encrypt them, never log them, and scope access tightly.
  • Do not send refresh tokens to the frontend. Use HTTPS end-to-end.
  • Monitor refresh attempts for invalid_grant errors — they often signal revocation or rotation mistakes.
  • Prefer short-lived access tokens paired with refresh tokens instead of long-lived access tokens.

References