Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langgenius Dify Refresh Token

From Leeroopedia
Knowledge Sources
Domains Frontend, API_Service
Last Updated 2026-02-12 07:00 GMT

Overview

Cross-tab token refresh coordination module that ensures only one browser tab refreshes the authentication token at a time, preventing race conditions and infinite refresh loops.

Description

refresh-token.ts implements a cross-tab synchronization mechanism for refreshing authentication tokens. When a 401 response is received, this module ensures that only a single browser tab performs the actual token refresh request, while other tabs wait for the result. It uses localStorage as a cross-tab communication channel with two keys: is_other_tab_refreshing (a lock flag set to "1" during refresh) and last_refresh_time (timestamp to detect stale locks). The getNewAccessToken function checks if another tab is already refreshing (via the localStorage flag and a local isRefreshing boolean) and either waits (polling every 1 second via waitUntilTokenRefreshed) or proceeds to refresh. The actual refresh is performed using fetchWithRetry with a direct globalThis.fetch call to /refresh-token (deliberately not using baseFetch to avoid infinite 401 loops). The refresh request uses credentials: "include" to send cookies containing the refresh token. The releaseRefreshLock function cleans up all locks and event listeners. The exported refreshAccessTokenOrReLogin function wraps the refresh in a Promise.race with a timeout, ensuring the process does not hang indefinitely. It also registers a beforeunload event listener to release the lock if the tab is closed during refresh.

Usage

This module is consumed internally by base.ts when a 401 response is encountered during any API call. It should not be called directly from application components. The refreshAccessTokenOrReLogin function is invoked with a timeout value (default 100000ms) and either resolves (allowing the failed request to be retried) or rejects (triggering a redirect to login).

Code Reference

Source Location

Signature

// Main exported function: refresh token or timeout
export async function refreshAccessTokenOrReLogin(timeout: number): Promise<void>

// Internal functions (not exported)
function waitUntilTokenRefreshed(): Promise<void>
function isRefreshingSignAvailable(delta: number): boolean
async function getNewAccessToken(timeout: number): Promise<void>
function releaseRefreshLock(): void

Import

import { refreshAccessTokenOrReLogin } from '@/service/refresh-token'

I/O Contract

Inputs

Name Type Required Description
timeout number Yes Maximum time in milliseconds to wait for the token refresh before rejecting with a timeout error

Outputs

Name Type Description
Promise<void> Promise<void> Resolves when token refresh succeeds (new cookie set by server); rejects on timeout, 401 from refresh endpoint, or network error

Usage Examples

Internal Usage in base.ts

import { refreshAccessTokenOrReLogin } from './refresh-token'

const TIME_OUT = 100000

// When a 401 is received from any API call:
const [refreshErr] = await asyncRunSafe(refreshAccessTokenOrReLogin(TIME_OUT))
if (refreshErr === null) {
  // Token refreshed successfully, retry the original request
  return baseFetch<T>(url, options, otherOptionsForBaseFetch)
}
// Refresh failed, redirect to login
jumpTo(loginUrl)

Cross-Tab Behavior

// Tab A: Encounters 401, starts refresh
// - Sets localStorage 'is_other_tab_refreshing' = '1'
// - Sets localStorage 'last_refresh_time' = timestamp
// - POSTs to /refresh-token with credentials

// Tab B: Encounters 401 while Tab A is refreshing
// - Detects localStorage lock is set and within timeout
// - Polls every 1000ms via waitUntilTokenRefreshed()
// - Resolves when Tab A clears the lock

// Tab A: Refresh completes
// - Clears localStorage lock
// - Tab B's poll detects clearance and resolves
// - Both tabs can now make authenticated requests

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment