亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【JavaScript】無感刷新Token:如何做到讓用戶“永不掉線”

admin
2025年7月9日 12:40 本文熱度 851

沒有什么比在用戶操作得正嗨時,突然提示“登錄已過期,請重新登錄”的提示更讓人沮喪的了。這種突兀的中斷不僅破壞了用戶體驗,甚至可能導致未保存的數(shù)據(jù)丟失。

然而,我們都知道,出于安全考慮,用于身份驗證的 Token(通常是 Access Token)必須有較短的有效期。那么,我們如何在保證安全的前提下,創(chuàng)造一種“永不掉線”的絲滑體驗呢?

問題的根源:Access Token 的“天生矛盾”

首先,我們要理解為什么需要刷新 Token。

我們通常使用 Access Token 來驗證用戶的每一次 API 請求。為了安全,Access Token 的生命周期被設計得很短(例如 30 分鐘或 1 小時)。如果有效期太長,一旦泄露,攻擊者就能在很長一段時間內冒充用戶進行操作,風險極高。

這就產生了一個矛盾:

  • 安全性要求Access Token 有效期要短。
  • 用戶體驗要求:用戶不想頻繁地被強制重新登錄。

為了解決這個矛盾,Refresh Token 應運而生。

核心理念:雙 Token 認證系統(tǒng)

無感刷新機制的核心在于引入了兩種類型的 Token:

  1. Access Token(訪問令牌)

    • 用途:用于訪問受保護的 API 資源,附加在每個請求的 Header 中。
    • 特點:生命周期短(如 1 小時),無狀態(tài),服務器無需存儲。
    • 存儲:通常存儲在客戶端內存中(如 Vuex/Redux),因為需要頻繁讀取。
  2. Refresh Token(刷新令牌)

    • 用途:當 Access Token 過期時,專門用于獲取一個新的 Access Token。
    • 特點:生命周期長(如 7 天或 30 天),與特定用戶綁定,服務器需要安全存儲其有效性記錄。
    • 存儲:必須安全存儲。最佳實踐是存儲在 HttpOnly Cookie 中,這樣可以防止客戶端 JavaScript 腳本(如 XSS 攻擊)讀取它。

既然如此,為何不直接使用 Refresh Token 呢?

Access Token 通常是無狀態(tài)的,服務器無需記錄它,也導致 JWT 無法主動吊銷,而 Refresh Token 是有狀態(tài)的,服務器需要一個列表(數(shù)據(jù)庫中的“白名單”或“吊銷列表”)來記錄哪些 Refresh Token 是有效的,當用戶更改密碼、或從某個設備上“主動登出”時,服務器端可以主動將對應的 Refresh Token 設為無效。

無感刷新的詳細工作流

下面是這個“魔法”發(fā)生的具體步驟:

  1. 首次登錄:用戶使用用戶名和密碼登錄。服務器驗證成功后,返回一個 Access Token 和一個 Refresh Token。
  2. 正常請求:客戶端將 Access Token 存儲起來,并在后續(xù)的每次 API 請求中,通過 Authorization 請求頭將其發(fā)送給服務器。
  3. Token 過期:當 Access Token 過期后,客戶端再次用它請求 API。服務器會拒絕該請求,并返回一個特定的狀態(tài)碼,通常是 401 Unauthorized。
  4. 攔截 401 錯誤:客戶端的請求層(如 Axios 攔截器)會捕獲這個 401 錯誤。此時,它不會立即通知用戶“你已掉線”,而是暫停這個失敗的請求。
  5. 發(fā)起刷新請求:攔截器使用 Refresh Token 去調用一個專門的刷新接口(例如 /api/auth/refresh)。
  6. 處理刷新結果
    • 刷新成功:服務器驗證 Refresh Token 有效,生成一個新的 Access Token(有時也會返回一個新的 Refresh Token,這被稱為“刷新令牌旋轉”策略,可以提高安全性),并將其返回給客戶端。
    • 刷新失敗:如果 Refresh Token 也過期了或無效,服務器會返回錯誤(如 403 Forbidden)。這意味著用戶的登錄會話徹底結束。
  7. 重試與終結
    • 若刷新成功:客戶端用新的 Access Token 自動重發(fā)剛才失敗的那個 API 請求。用戶完全感覺不到任何中斷,數(shù)據(jù)操作無縫銜接。
    • 若刷新失敗:客戶端清除所有認證信息,強制用戶登出,并重定向到登錄頁面。

實戰(zhàn)演練:使用 Axios 攔截器實現(xiàn)無感刷新

Axios 的攔截器是實現(xiàn)這一流程的完美工具。下面是一個完整且考慮了并發(fā)問題的實現(xiàn)方案。

1. 創(chuàng)建 Axios 實例

首先,我們創(chuàng)建一個單獨的 Axios 實例,方便統(tǒng)一管理。

// a-pi/request.js
import axios from 'axios';

const service = axios.create({
 baseURL: '/api',
 timeout: 10000,
});

// 請求攔截器
service.interceptors.request.use(
 config => {
    // 在發(fā)送請求之前,從 state management (e.g., Vuex/Pinia/Redux) 獲取 token
    const accessToken = getAccessTokenFromStore(); 
    if (accessToken) {
      config.headers['Authorization'] = `Bearer ${accessToken}`;
    }
    return config;
  },
 error => {
    return Promise.reject(error);
  }
);

2. 核心:響應攔截器

這是實現(xiàn)無感刷新的關鍵。

// a-pi/request.js (續(xù))

// 用于刷新 token 的 API
import { refreshTokenApi } from './auth'

let isRefreshing = false; // 控制刷新狀態(tài)的標志
let requests = []; // 存儲因 token 過期而掛起的請求

service.interceptors.response.use(
 response => response, // 對成功響應直接返回
 async error => {
    const { config, response: { status } } = error;
    
    // 1. 如果不是 401 錯誤,直接返回錯誤
    if (status !== 401) {
      return Promise.reject(error);
    }

    // 2. 避免重復刷新:如果正在刷新 token,將后續(xù)請求暫存
    if (isRefreshing) {
      return new Promise(resolve => {
        requests.push(() => resolve(service(config)));
      });
    }

    isRefreshing = true;

    try {
      // 3. 調用刷新 token 的 API
      const { newAccessToken } = await refreshTokenApi(); // 假設 refresh token 通過 HttpOnly cookie 自動發(fā)送

      // 4. 更新本地存儲的 access token
      setAccessTokenInStore(newAccessToken);
      
      // 5. 重試剛才失敗的請求
      config.headers['Authorization'] = `Bearer ${newAccessToken}`;
      
      // 6. 重新執(zhí)行所有被掛起的請求
      requests.forEach(cb => cb());
      requests = []; // 清空隊列
      
      return service(config); // 返回重試請求的結果
    } catch (refreshError) {
      // 7. 如果刷新 token 也失敗了,則執(zhí)行登出操作
      console.error('Unable to refresh token.', refreshError);
      logoutUser(); // 清除 token,重定向到登錄頁
      return Promise.reject(refreshError);
    } finally {
      isRefreshing = false;
    }
  }
);

export default service;

代碼解析:

  • 并發(fā)處理isRefreshing 標志和 requests 數(shù)組是關鍵。當?shù)谝粋€ 401 錯誤觸發(fā)刷新時,isRefreshing 變?yōu)?nbsp;true。后續(xù)在刷新完成前到達的 401 請求,都會被推進 requests 隊列中掛起,而不是重復發(fā)起刷新請求。當刷新成功后,再遍歷隊列,依次執(zhí)行這些被掛起的請求。
  • 原子操作:通過這種“加鎖”機制,確保了刷新 Token 的操作是原子的,避免了資源浪費和潛在的競態(tài)條件。
  • 優(yōu)雅降級:當 Refresh Token 也失效時,系統(tǒng)會執(zhí)行 logoutUser(),進行清理工作并引導用戶重新登錄,這是一個優(yōu)雅的失敗處理方案。

無感刷新 Token 機制是現(xiàn)代 Web 應用提升用戶體驗的“標配”。它將身份驗證的復雜性隱藏在后臺,為用戶提供了一個流暢、不間斷的操作環(huán)境。

實現(xiàn)這一機制,不僅僅是寫幾行代碼,更是對認證流程、安全性和用戶體驗三者之間平衡的深刻理解。


該文章在 2025/7/9 12:40:23 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved