最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue前后端實(shí)現(xiàn)token自動續(xù)期的方法詳解

 更新時間:2026年03月11日 09:09:04   作者:高并發(fā)吃面  
在前后端分離架構(gòu)中,Token 是實(shí)現(xiàn)身份認(rèn)證的核心機(jī)制,但 Token 過期會導(dǎo)致用戶操作中斷,因此自動續(xù)期方案是保障用戶持續(xù)訪問的關(guān)鍵,下面小編就和大家介紹幾個主流的 Token 自動續(xù)期方案吧

在前后端分離架構(gòu)中,Token 是實(shí)現(xiàn)身份認(rèn)證的核心機(jī)制,但 Token 過期會導(dǎo)致用戶操作中斷,影響體驗(yàn)。因此,自動續(xù)期方案是保障用戶持續(xù)訪問的關(guān)鍵。以下是幾種主流的 Token 自動續(xù)期方案,包含原理、實(shí)現(xiàn)細(xì)節(jié)及安全性考量。

一、刷新 Token(Refresh Token)機(jī)制

這是目前最成熟、應(yīng)用最廣泛的方案,核心是通過“雙 Token 體系”實(shí)現(xiàn)續(xù)期,兼顧安全性和用戶體驗(yàn)。

1. 核心原理

  • Access Token(訪問令牌):短期有效(如 15 分鐘),用于接口訪問,權(quán)限范圍小,泄露風(fēng)險(xiǎn)低。
  • Refresh Token(刷新令牌):長期有效(如 7 天),僅用于獲取新的 Access Token,權(quán)限范圍僅為“續(xù)期”,泄露影響可控。

當(dāng) Access Token 過期時,前端用未過期的 Refresh Token 向后端換取新的 Access Token,避免用戶重新登錄。

2. 前后端實(shí)現(xiàn)流程

前端實(shí)現(xiàn)(以 Axios 為例)

1.存儲 Token:Access Token 存在內(nèi)存或 httpOnly Cookie(推薦,防 XSS);Refresh Token 存在 httpOnly Cookie(避免前端 JS 讀取,增強(qiáng)安全性)。

2.請求攔截器:每次請求在 Header 中攜帶 Access Token(如 Authorization: Bearer {accessToken})。

3.響應(yīng)攔截器:處理 401 錯誤(Access Token 過期):

  • 若存在 Refresh Token,調(diào)用后端“刷新接口”獲取新 Access Token。
  • 刷新成功后,更新本地 Access Token,并重試原請求。
  • 若 Refresh Token 也過期(刷新接口返回 401),則清除本地 Token,跳轉(zhuǎn)至登錄頁。
// 響應(yīng)攔截器示例
axios.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    // 若為401且未嘗試過刷新
    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true; // 標(biāo)記已嘗試刷新,避免重復(fù)請求
      try {
        // 調(diào)用刷新接口(Refresh Token 通過 Cookie 自動攜帶)
        const { data } = await axios.post('/api/refresh-token');
        // 更新本地 Access Token
        localStorage.setItem('accessToken', data.accessToken);
        // 重試原請求(攜帶新 Token)
        originalRequest.headers['Authorization'] = `Bearer ${data.accessToken}`;
        return axios(originalRequest);
      } catch (refreshError) {
        // 刷新失?。≧efresh Token 過期),跳轉(zhuǎn)登錄
        window.location.href = '/login';
        return Promise.reject(refreshError);
      }
    }
    return Promise.reject(error);
  }
);

4.并發(fā)請求處理:若多個請求同時觸發(fā) 401,需避免重復(fù)刷新 Token??赏ㄟ^“鎖機(jī)制”實(shí)現(xiàn):刷新過程中阻塞其他請求,等待新 Token 生成后統(tǒng)一重試。

后端實(shí)現(xiàn)

1.生成 Token:登錄成功時,同時生成 Access Token(短期)和 Refresh Token(長期),返回給前端(Access Token 可放響應(yīng)體,Refresh Token 放 httpOnly Cookie)。

2.驗(yàn)證 Access Token:接口請求時,驗(yàn)證 Access Token 的簽名和有效期,無效則返回 401。

3.刷新接口實(shí)現(xiàn)

  • 接收 Refresh Token(從 Cookie 或請求體獲?。?yàn)證其有效性(是否存在于數(shù)據(jù)庫、未過期、未被吊銷)。
  • 驗(yàn)證通過后,生成新的 Access Token(和新的 Refresh Token,可選,增強(qiáng)安全性)。
  • 返回新 Token 給前端。
// 后端刷新接口示例(偽代碼)
@PostMapping("/api/refresh-token")
public Result refreshToken(HttpServletRequest request) {
  // 從 Cookie 獲取 Refresh Token
  String refreshToken = CookieUtils.getCookieValue(request, "refreshToken");
  if (refreshToken == null) {
    return Result.fail(401, "刷新令牌不存在");
  }
  // 驗(yàn)證 Refresh Token(查庫+驗(yàn)簽)
  RefreshTokenEntity entity = refreshTokenMapper.selectByToken(refreshToken);
  if (entity == null || entity.getExpireTime().before(new Date())) {
    return Result.fail(401, "刷新令牌已過期");
  }
  // 生成新 Access Token 和 Refresh Token
  String newAccessToken = JwtUtils.generateAccessToken(entity.getUserId());
  String newRefreshToken = JwtUtils.generateRefreshToken(entity.getUserId());
  // 更新數(shù)據(jù)庫中的 Refresh Token(舊的標(biāo)記失效,存儲新的)
  refreshTokenMapper.invalidateOldToken(entity.getId());
  refreshTokenMapper.insert(new RefreshTokenEntity(newRefreshToken, entity.getUserId()));
  // 返回新 Token(Access Token 放響應(yīng)體,Refresh Token 放 httpOnly Cookie)
  return Result.success(Map.of(
    "accessToken", newAccessToken,
    "refreshToken", newRefreshToken // 可選,通過 Cookie 返回更安全
  ));
}

3. 優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):安全性高(Access Token 短期有效,泄露影響?。籖efresh Token 可吊銷);用戶體驗(yàn)好(無需頻繁登錄)。
  • 缺點(diǎn):實(shí)現(xiàn)較復(fù)雜(需維護(hù)雙 Token 邏輯);需后端存儲 Refresh Token(增加存儲成本)。

二、滑動窗口續(xù)期(無 Refresh Token)

適用于對安全性要求中等、希望簡化實(shí)現(xiàn)的場景,核心是“Token 快過期時自動延長有效期”。

1. 核心原理

  • 僅使用一個 Access Token,有效期設(shè)為中等(如 1 小時)。
  • 當(dāng) Token 剩余有效期小于閾值(如 10 分鐘)時,前端請求接口時,后端自動生成新 Token 并返回,前端更新本地 Token。
  • 本質(zhì)是“用持續(xù)活躍的請求延長 Token 有效期”,類似“用戶活躍則會話不失效”。

2. 前后端實(shí)現(xiàn)流程

前端實(shí)現(xiàn)

存儲 Token 并在請求頭攜帶。

每次收到響應(yīng)后,檢查是否包含新 Token(如響應(yīng)頭 X-New-Token),若有則更新本地存儲。

// 響應(yīng)攔截器示例
axios.interceptors.response.use(
  (response) => {
    // 若響應(yīng)頭有新 Token,更新本地存儲
    const newToken = response.headers['x-new-token'];
    if (newToken) {
      localStorage.setItem('accessToken', newToken); // 建議用 Cookie
    }
    return response;
  },
  (error) => {
    // 若 Token 已過期(401),直接跳轉(zhuǎn)登錄
    if (error.response?.status === 401) {
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

后端實(shí)現(xiàn)

Token 中包含過期時間(如 exp 字段)。

每次驗(yàn)證 Token 時,計(jì)算剩余有效期:若剩余時間 < 閾值(如 10 分鐘),則生成新 Token,放在響應(yīng)頭(如 X-New-Token)返回。

// 驗(yàn)證 Token 并判斷是否續(xù)期(偽代碼)
public String validateAndRenewToken(String token) {
  // 驗(yàn)證 Token 簽名和有效性
  Claims claims = JwtUtils.parseToken(token);
  if (claims == null) {
    throw new TokenInvalidException();
  }
  // 計(jì)算剩余有效期(當(dāng)前時間到 exp 的差值)
  long expireTime = claims.getExpiration().getTime();
  long remainingTime = expireTime - System.currentTimeMillis();
  // 若剩余時間 < 10 分鐘,生成新 Token
  if (remainingTime < 10 * 60 * 1000) {
    String newToken = JwtUtils.generateAccessToken(claims.getSubject()); // 用原用戶 ID 生成新 Token
    return newToken;
  }
  return null; // 無需續(xù)期
}

3. 優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):實(shí)現(xiàn)簡單(無需維護(hù) Refresh Token);用戶體驗(yàn)流暢(無感續(xù)期)。
  • 缺點(diǎn):安全性較低(Token 有效期較長,泄露后風(fēng)險(xiǎn)更高);無法處理“用戶長時間不操作”的場景(Token 會直接過期)。

三、主動預(yù)檢續(xù)期

適用于對請求成功率要求高的場景,前端主動檢測 Token 有效期,提前續(xù)期。

1. 核心原理

  • 前端每次發(fā)送請求前,檢查 Token 剩余有效期:
    • 若剩余時間 > 閾值(如 5 分鐘):直接發(fā)送請求。
    • 若剩余時間 ≤ 閾值:先發(fā)送續(xù)期請求獲取新 Token,再發(fā)送原請求。
  • 避免了“請求因 Token 過期失敗后重試”的情況,更主動。

2. 前后端實(shí)現(xiàn)流程

前端實(shí)現(xiàn)(請求攔截器中處理)

axios.interceptors.request.use(async (config) => {
  const token = localStorage.getItem('accessToken');
  if (!token) {
    window.location.href = '/login';
    return Promise.reject(new Error('未登錄'));
  }
  // 解析 Token 中的過期時間(需前端解析 JWT,或后端返回過期時間)
  const payload = JSON.parse(atob(token.split('.')[1]));
  const expireTime = payload.exp * 1000; // JWT 的 exp 是秒級時間戳
  const remainingTime = expireTime - Date.now();
  
  // 若剩余時間 ≤ 5 分鐘,先續(xù)期
  if (remainingTime <= 5 * 60 * 1000) {
    try {
      const { data } = await axios.post('/api/renew-token', { token });
      const newToken = data.newToken;
      localStorage.setItem('accessToken', newToken);
      config.headers['Authorization'] = `Bearer ${newToken}`;
    } catch (error) {
      // 續(xù)期失敗,跳轉(zhuǎn)登錄
      window.location.href = '/login';
      return Promise.reject(error);
    }
  } else {
    config.headers['Authorization'] = `Bearer ${token}`;
  }
  return config;
});

后端實(shí)現(xiàn)

  • 提供專門的續(xù)期接口(/api/renew-token),接收舊 Token,驗(yàn)證有效性后返回新 Token。
  • 邏輯與滑動窗口的后端類似,但觸發(fā)時機(jī)由前端主動控制。

3. 優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):避免請求失敗重試,成功率高;主動處理續(xù)期,流程更可控。
  • 缺點(diǎn):增加了一次預(yù)檢請求(性能損耗?。恍枨岸私馕?Token 過期時間(JWT 可解析,非 JWT 需后端額外返回)。

四、安全性與最佳實(shí)踐

Token 存儲

  • 優(yōu)先用 httpOnly + Secure + SameSite Cookie 存儲(防 XSS、CSRF 攻擊)。
  • 避免用 localStorage/sessionStorage(易被 XSS 竊取)。

過期時間設(shè)置

  • Access Token:短期(15 分鐘 ~ 1 小時),減少泄露影響。
  • Refresh Token:中期(7 ~ 30 天),兼顧體驗(yàn)與安全;可設(shè)置“絕對過期時間”(如 30 天),強(qiáng)制用戶定期登錄。

Refresh Token 輪換:每次用 Refresh Token 換取新 Access Token 時,同步生成新的 Refresh Token(舊的立即失效),防止 Refresh Token 被復(fù)用。

HTTPS 傳輸:所有 Token 必須通過 HTTPS 傳輸,防止中間人攻擊。

并發(fā)請求處理:用“鎖機(jī)制”(如 Promise 等待)處理多個請求同時觸發(fā)續(xù)期的場景,避免重復(fù)調(diào)用刷新接口。

Token 吊銷:后端需支持主動吊銷 Token(如用戶登出、修改密碼時),可通過“黑名單”(Redis 存儲已吊銷 Token)實(shí)現(xiàn)快速驗(yàn)證。

總結(jié)

  • 追求安全性:優(yōu)先選 Refresh Token 機(jī)制(雙 Token 體系)。
  • 追求簡單實(shí)現(xiàn):選 滑動窗口續(xù)期(無 Refresh Token)。
  • 追求請求成功率:選 主動預(yù)檢續(xù)期(前端提前處理)。

實(shí)際場景中,可結(jié)合業(yè)務(wù)需求(如用戶活躍度、安全等級)選擇方案,核心是在“用戶體驗(yàn)”與“安全性”之間找到平衡。

到此這篇關(guān)于Vue前后端實(shí)現(xiàn)token自動續(xù)期的方法詳解的文章就介紹到這了,更多相關(guān)前后端token續(xù)期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue實(shí)現(xiàn)雙向綁定的原理以及響應(yīng)式數(shù)據(jù)的方法

    Vue實(shí)現(xiàn)雙向綁定的原理以及響應(yīng)式數(shù)據(jù)的方法

    這篇文章主要介紹了Vue實(shí)現(xiàn)雙向綁定的原理以及響應(yīng)式數(shù)據(jù)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • 前端vue3?setup使用教程

    前端vue3?setup使用教程

    這篇文章主要為大家介紹了前端vue3架構(gòu)setup使用教程,詳細(xì)介紹?setup?的用法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-02-02
  • Vue前端空值處理的實(shí)戰(zhàn)指南與避坑記錄

    Vue前端空值處理的實(shí)戰(zhàn)指南與避坑記錄

    本文旨在幫助同學(xué)們學(xué)會在前端真實(shí)業(yè)務(wù)項(xiàng)目里,到底該怎么寫空值處理(?.、??、||、if判斷、兜底邏輯),以及為什么這么選、會踩哪些高頻坑,順便幫大家拉直JS/TS空值、真值假值的基礎(chǔ)概念,助力你們寫出規(guī)范可維護(hù)的團(tuán)隊(duì)級代碼
    2026-03-03
  • vue3+ts重復(fù)參數(shù)提取成方法多處調(diào)用以及字段無值時不傳字段給后端問題

    vue3+ts重復(fù)參數(shù)提取成方法多處調(diào)用以及字段無值時不傳字段給后端問題

    在進(jìn)行API開發(fā)時,優(yōu)化參數(shù)傳遞是一個重要的考量,傳統(tǒng)方法中,即使參數(shù)值為空,也會被包含在請求中發(fā)送給后端,這可能會導(dǎo)致不必要的數(shù)據(jù)處理,而優(yōu)化后的方法則只會傳遞那些實(shí)際有值的字段,從而提高數(shù)據(jù)傳輸?shù)挠行院秃蠖颂幚淼男?/div> 2024-10-10
  • vue-cli 3.0 自定義vue.config.js文件,多頁構(gòu)建的方法

    vue-cli 3.0 自定義vue.config.js文件,多頁構(gòu)建的方法

    今天小編就為大家分享一篇vue-cli 3.0 自定義vue.config.js文件,多頁構(gòu)建的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue使用JSEncrypt實(shí)現(xiàn)rsa加密及掛載方法

    Vue使用JSEncrypt實(shí)現(xiàn)rsa加密及掛載方法

    這篇文章主要介紹了Vue使用JSEncrypt實(shí)現(xiàn)rsa加密及掛載方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • vite2.x實(shí)現(xiàn)按需加載ant-design-vue@next組件的方法

    vite2.x實(shí)現(xiàn)按需加載ant-design-vue@next組件的方法

    這篇文章主要介紹了vite2.x實(shí)現(xiàn)按需加載ant-design-vue@next組件的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Vue頁面中實(shí)現(xiàn)平滑滾動功能

    Vue頁面中實(shí)現(xiàn)平滑滾動功能

    這是一個實(shí)現(xiàn)平滑滾動的函數(shù),可以讓頁面在滾動到指定位置時產(chǎn)生緩動效果,本文給大家介紹了如何在在Vue頁面中實(shí)現(xiàn)平滑滾動功能,<BR>,文中詳細(xì)的代碼講解供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-12-12
  • vue中動態(tài)組件使用及傳值方式

    vue中動態(tài)組件使用及傳值方式

    這篇文章主要介紹了vue中動態(tài)組件使用及傳值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue 項(xiàng)目常用加載器及配置詳解

    vue 項(xiàng)目常用加載器及配置詳解

    本文介紹了vue 項(xiàng)目常用加載器及配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01

最新評論

阳春市| 铁岭县| 城固县| 双桥区| 苏尼特左旗| 临西县| 婺源县| 奉贤区| 砀山县| 江阴市| 唐山市| 卢龙县| 汽车| 乌鲁木齐县| 衡阳县| 黔南| 都安| 梧州市| 九江市| 浙江省| 讷河市| 华容县| 南阳市| 瑞安市| 榕江县| 夏津县| 泗洪县| 赤水市| 钟祥市| 镇宁| 江西省| 报价| 攀枝花市| 乐至县| 清苑县| 利川市| 德昌县| 滦南县| 江阴市| 平顶山市| 恭城|