loading
Preparing LoginRadius developer resources
Mission: Help enterprises accelerate digital transformation with our fully-managed Customer IAM technology.
Skip to main content

Refresh Token Flow

A refresh_token is a long-lived credential issued alongside the access_token during a successful authentication. It allows the client to obtain a new access_token — and a new refresh_token — without requiring the user to re-authenticate, as long as the refresh token is valid and has not been revoked.

This page covers the end-to-end refresh token flow as implemented by LoginRadius, including the token request, rotation behaviour, and the optional Overlap Window (ReuseInterval) that adds replay-safe reliability for clients on unreliable networks.


Overview

The refresh token flow operates entirely as a back-channel call — no browser interaction or user login is required:

  1. The client detects that the access_token has expired (or is about to expire).
  2. The client makes a direct POST request to the LoginRadius Token endpoint with grant_type=refresh_token and the stored refresh_token.
  3. LoginRadius validates the token and, if valid, issues a new access_token, refresh_token, and id_token.
  4. The old refresh_token is immediately invalidated — this is refresh token rotation, and it is always active on LoginRadius.

Flow Diagram


Step-by-Step Walkthrough

Step 1 — Detect Token Expiry

The client should proactively check whether the access_token is nearing expiry using the expires_in value returned during the original authentication or a prior refresh. Waiting for a 401 Unauthorized from a protected API is also a valid trigger.

Best practice: Refresh the access_token slightly before expires_in elapses (e.g., 60 seconds before), rather than waiting for an API call to fail. This avoids latency-sensitive failures in production.


Step 2 — Token Refresh Request

The client makes a direct POST call to the LoginRadius Token endpoint. This call never goes through the browser.

Endpoint

POST https://{SiteURL}/api/oidc/{OIDCAppName}/token

SiteURL = Either <TenantName>.hub.loginradius.com or a Custom Domain i.e. auth.your-app.com. OIDCAppName = your configured OIDC App name.

The token endpoint accepts application/x-www-form-urlencoded as the content type for refresh token requests.

The client_id and client_secret are included directly in the request body.

POST /api/oidc/{OIDCAppName}/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token={your_refresh_token}
&client_id=YOUR_OIDC_CLIENT_ID
&client_secret=YOUR_OIDC_CLIENT_SECRET

Step 3 — Token Validation

LoginRadius validates the incoming refresh token against the following conditions. If any check fails, a 400 invalid_grant is returned and the client must initiate a new authentication flow.

ValidationDescription
Token existsThe refresh token is present in the token store
Token not expiredThe refresh token has not exceeded its configured TTL
Token not revokedThe token has not been explicitly revoked via a logout or revocation call
Token not already usedThe token has not been used in a prior rotation cycle (subject to ReuseInterval — see below)
Client matchThe client_id in the request matches the client_id the token was issued for

Step 4 — Token Issuance & Rotation

Upon successful validation, LoginRadius:

  1. Invalidates the old refresh_token — it can no longer be used for subsequent refreshes.
  2. Issues a new token set — a new access_token, refresh_token, and id_token.
  3. Returns the new tokens to the client.

The client must replace its stored token pair with the newly returned tokens immediately.

Success Response

{
"access_token": "<New LoginRadius JWT Access Token>",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "<New Refresh Token>",
"id_token": "<New JWT ID Token>"
}

Error Response

{
"error": "invalid_grant",
"error_description": "The refresh_token is not valid",
}

Token Request Parameters

ParameterRequiredDescription
grant_type✅ RequiredMust be refresh_token
refresh_token✅ RequiredThe refresh token issued during the previous authentication or refresh
client_id✅ RequiredYour OIDC application client_id
client_secret✅ Required (confidential clients)Your OIDC application client_secret. Not required for PKCE / public clients.

Token Response Fields

FieldDescription
access_tokenNew LoginRadius JWT — use this to call protected APIs
token_typeAlways Bearer
expires_inLifetime of the new access token in seconds
refresh_tokenNew refresh token — replace the old one immediately
id_tokenJWT containing updated identity claims about the authenticated user

Refresh Token Rotation

LoginRadius enforces refresh token rotation on every use. Each time a refresh token is used, it is invalidated and a new token pair is issued in its place. This limits the damage window if a refresh token is stolen — any replay of the old token will fail because it has already been cycled.

Important: Always replace the stored refresh_token with the newly issued one before making any subsequent API calls. Holding onto a used token is the most common cause of invalid_grant errors.


Refresh Token Rotation with Overlap Window (ReuseInterval)

Standard rotation creates a reliability problem on unreliable networks: if LoginRadius rotates the token but the network drops the response before the client receives it, the client retries with the now-invalidated original token and receives a permanent invalid_grant — forcing a full re-authentication even though nothing went wrong.

The Overlap Window (ReuseInterval) solves this by allowing the same refresh token to be safely replayed within a short, configurable grace period. During this window, LoginRadius recognises the replay and returns the same token set that was issued on the first use. After the window expires, the token is permanently rejected and full rotation security is restored.

How the Overlap Window Works

  1. The client sends a refresh request with RT1.
  2. LoginRadius validates RT1 and issues a new token pair (AT2, RT2, IDT2).
  3. RT1 is now used. For the duration of ReuseInterval, LoginRadius still recognizes RT1 as a valid replay rather than rejecting it outright.
  4. If the network drops the response: the client retries with RT1. LoginRadius recognizes the replay and returns the same AT2, RT2, IDT2 with a recalculated expires_in. The response is idempotent.
  5. Once ReuseInterval elapses, RT1 is no longer recognized. Any further replay of RT1 returns 400 invalid_grant.

Configuration

ReuseInterval is set on the OIDC application's OAuth configuration under Refresh Token Rotation section:

FieldTypeDefaultValid RangeDescription
ReuseIntervalinteger00–60 secondsGrace period during which a used refresh token can be safely replayed. 0 disables the overlap window and standard single-use rotation applies.

Recommendation: Set ReuseInterval between 5 and 30 seconds — long enough to absorb a network-level retry, short enough to minimise the window in which a stolen token could be replayed. Values outside 0–60 are rejected at configuration time.

Overlap Window Behaviour Reference

ScenarioReuseIntervalOutcome
First use of a refresh tokenAnyNew token pair issued; old token marked as used
Replay within the overlap window> 0Same token pair returned (idempotent); expires_in recalculated
Replay after the overlap window expires> 0400 invalid_grant
Any replay0 (disabled)400 invalid_grant
Explicit token revocation, then replayAny400 invalid_grant

Security Properties of the Overlap Window

Enabling ReuseInterval does not weaken rotation security in meaningful ways, but the following properties should be understood:

PropertyBehaviour
Stolen token replayed within the windowThe attacker and the legitimate client receive the same token set. The next rotation cycle will detect divergence if the attacker attempts to use the received tokens.
Stolen token replayed after the window expiresRejected — 400 invalid_grant. Full rotation security applies.
Explicit revocationThe token is rejected immediately, even if it is still within its ReuseInterval window.

ReuseInterval must always be significantly smaller than the refresh token TTL to preserve the security properties of rotation.