Back to Grant Types
Token RenewalID: refresh_token

Refresh Token Flow

Renew expired access tokens seamlessly in the background without forcing the user to re-authenticate or re-enter credentials.

#oauth2#refresh-token#token-renewal#rotation#security#oidc

Overview

Access tokens are intentionally designed to be short-lived (typically lasting from 15 minutes to a few hours) to minimize the risk window if a token is intercepted or leaked.

The Refresh Token Flow (RFC 6749 Section 6) allows a client application to obtain a new access token without user involvement once the current access token expires.

Modern security architectures enforce Refresh Token Rotation: every time a refresh token is presented, the authorization server invalidates it and issues a brand-new refresh token. If an invalidated refresh token is ever presented again, the authorization server recognizes a potential token theft and revokes all tokens for that user session.

Quick Specifications

Flow Status
standard
Recommended For
Web ApplicationSPA (Single Page Application)Mobile ApplicationDesktop ApplicationCLI
Token Auth Methods
NoneClient Secret BasicClient Secret Post
Primary Standard
RFC 6749 Section 6

Sequence Diagram

Visual sequence illustrating entity interactions and protocol steps

Sequence Diagram
Interactive Diagram
sequenceDiagram
    autonumber
    participant C as Client Application
    participant AS as Authorization Server
    participant RS as Resource Server (API)

    C->>RS: GET /api/user (Authorization: Bearer EXPIRED_TOKEN)
    RS-->>C: 401 Unauthorized (token_expired)
    C->>AS: POST /oauth/token (grant_type=refresh_token, refresh_token=RT_1, client_id)
    AS->>AS: Validate refresh token & check expiration
    Note over AS: Refresh Token Rotation: Invalidate RT_1 & generate RT_2
    AS-->>C: 200 OK (access_token=NEW_AT, refresh_token=RT_2, expires_in=3600)
    C->>C: Store new tokens & update session
    C->>RS: Retry GET /api/user (Authorization: Bearer NEW_AT)
    RS-->>C: 200 OK (User Profile Data)

Step-by-Step Flow Breakdown

Detailed breakdown of every message exchange, query parameter, and HTTP payload

1

API Rejection on Expired Token

Client Application→Resource Server (API)

The client makes an API call, but the access token has expired. The API responds with an HTTP 401 Unauthorized status.

Expired Token Rejection
GET /api/v1/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...EXPIRED

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="The access token expired"
2

Request New Access Token

Client Application→Authorization Server

The client catches the 401 response and calls the token endpoint with grant_type=refresh_token and its current refresh_token.

Refresh Token Request
POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=rF4k91Z3lK...previous_refresh_token
&client_id=my_client_id
3

Validate Token & Rotate

Authorization Server→Authorization Server

The authorization server verifies the refresh token signature, ensures it has not been revoked or previously redeemed, and creates a new rotated refresh token.

4

Issue New Tokens

Authorization Server→Client Application

The authorization server returns a new access token along with a new refresh token, immediately invalidating the previous refresh token.

Rotated Token Response
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...NEW_ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "sM8v02B5kL...NEW_ROTATED_REFRESH_TOKEN",
  "scope": "openid profile email"
}
5

Retry Original API Call

Client Application→Resource Server (API)

The client transparently retries the user original API call with the newly acquired access token.

Successful Retried API Call
GET /api/v1/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...NEW_ACCESS_TOKEN

HTTP/1.1 200 OK
Content-Type: application/json

{
  "user_id": "usr_12345",
  "email": "alex@example.com"
}

Security Considerations

Critical safeguards, threat mitigations, and implementation best practices

Refresh Token Rotation (RTR)

Always enable refresh token rotation. Each refresh token should only be redeemed once. Issuing a new refresh token on every renewal prevents replay attacks.

Automatic Reuse Detection

If an already-redeemed refresh token is presented again, the authorization server must treat it as a token theft incident and immediately invalidate all tokens associated with the user session.

Secure Client Storage

Store refresh tokens in secure HTTP-only cookies with SameSite=Lax/Strict, or encrypted native keychain storage (iOS Keychain, Android Keystore). Never store refresh tokens in localStorage.

Specifications & Standards

Official IETF RFCs and OpenID Foundation standards defining this flow

Client Templates using this Grant Type

Explore ready-to-use client configurations supporting Refresh Token

All templates

Other OAuth 2.0 Grant Types

Compare with other authentication and authorization flows