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

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

【JavaScript】無(wú)感刷新Token:如何做到讓用戶(hù)“永不掉線”

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

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

然而,我們都知道,出于安全考慮,用于身份驗(yàn)證的 Token(通常是 Access Token)必須有較短的有效期。那么,我們?nèi)绾卧诒WC安全的前提下,創(chuàng)造一種“永不掉線”的絲滑體驗(yàn)?zāi)兀?/span>

問(wèn)題的根源:Access Token 的“天生矛盾”

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

我們通常使用 Access Token 來(lái)驗(yàn)證用戶(hù)的每一次 API 請(qǐng)求。為了安全,Access Token 的生命周期被設(shè)計(jì)得很短(例如 30 分鐘或 1 小時(shí))。如果有效期太長(zhǎng),一旦泄露,攻擊者就能在很長(zhǎng)一段時(shí)間內(nèi)冒充用戶(hù)進(jìn)行操作,風(fēng)險(xiǎn)極高。

這就產(chǎn)生了一個(gè)矛盾:

  • 安全性要求Access Token 有效期要短。
  • 用戶(hù)體驗(yàn)要求:用戶(hù)不想頻繁地被強(qiáng)制重新登錄。

為了解決這個(gè)矛盾,Refresh Token 應(yīng)運(yùn)而生。

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

無(wú)感刷新機(jī)制的核心在于引入了兩種類(lèi)型的 Token:

  1. Access Token(訪問(wèn)令牌)

    • 用途:用于訪問(wèn)受保護(hù)的 API 資源,附加在每個(gè)請(qǐng)求的 Header 中。
    • 特點(diǎn):生命周期短(如 1 小時(shí)),無(wú)狀態(tài),服務(wù)器無(wú)需存儲(chǔ)。
    • 存儲(chǔ):通常存儲(chǔ)在客戶(hù)端內(nèi)存中(如 Vuex/Redux),因?yàn)樾枰l繁讀取。
  2. Refresh Token(刷新令牌)

    • 用途:當(dāng) Access Token 過(guò)期時(shí),專(zhuān)門(mén)用于獲取一個(gè)新的 Access Token。
    • 特點(diǎn):生命周期長(zhǎng)(如 7 天或 30 天),與特定用戶(hù)綁定,服務(wù)器需要安全存儲(chǔ)其有效性記錄。
    • 存儲(chǔ):必須安全存儲(chǔ)。最佳實(shí)踐是存儲(chǔ)在 HttpOnly Cookie 中,這樣可以防止客戶(hù)端 JavaScript 腳本(如 XSS 攻擊)讀取它。

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

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

無(wú)感刷新的詳細(xì)工作流

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

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

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

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

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

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

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

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

// 請(qǐng)求攔截器
service.interceptors.request.use(
 config => {
    // 在發(fā)送請(qǐng)求之前,從 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. 核心:響應(yīng)攔截器

這是實(shí)現(xiàn)無(wú)感刷新的關(guān)鍵。

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

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

let isRefreshing = false; // 控制刷新?tīng)顟B(tài)的標(biāo)志
let requests = []; // 存儲(chǔ)因 token 過(guò)期而掛起的請(qǐng)求

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

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

    isRefreshing = true;

    try {
      // 3. 調(diào)用刷新 token 的 API
      const { newAccessToken } = await refreshTokenApi(); // 假設(shè) refresh token 通過(guò) HttpOnly cookie 自動(dòng)發(fā)送

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

export default service;

代碼解析:

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

無(wú)感刷新 Token 機(jī)制是現(xiàn)代 Web 應(yīng)用提升用戶(hù)體驗(yàn)的“標(biāo)配”。它將身份驗(yàn)證的復(fù)雜性隱藏在后臺(tái),為用戶(hù)提供了一個(gè)流暢、不間斷的操作環(huán)境。

實(shí)現(xiàn)這一機(jī)制,不僅僅是寫(xiě)幾行代碼,更是對(duì)認(rèn)證流程、安全性和用戶(hù)體驗(yàn)三者之間平衡的深刻理解。


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