偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

前端實(shí)現(xiàn)無(wú)縫刷新 Token

開(kāi)發(fā) 前端
在前端開(kāi)發(fā)中,經(jīng)常會(huì)遇到 Token續(xù)約 的問(wèn)題。對(duì) Token 實(shí)現(xiàn)無(wú)縫刷新從而維護(hù)用戶的登錄狀態(tài)無(wú)論是在開(kāi)發(fā)時(shí),還是在 面試時(shí)都是至關(guān)重要的。所以說(shuō)咱們今天就來(lái)看看 Token 的無(wú)縫刷新問(wèn)題。

在前端開(kāi)發(fā)中,經(jīng)常會(huì)遇到 Token續(xù)約 的問(wèn)題。對(duì) Token 實(shí)現(xiàn)無(wú)縫刷新從而維護(hù)用戶的登錄狀態(tài)無(wú)論是在開(kāi)發(fā)時(shí),還是在 面試時(shí)都是至關(guān)重要的。所以說(shuō)咱們今天就來(lái)看看 Token 的無(wú)縫刷新問(wèn)題。

一、前端無(wú)縫刷新令牌的原理

1、令牌過(guò)期

服務(wù)器為每個(gè)令牌設(shè)置一個(gè)過(guò)期時(shí)間,通常是30分鐘或1小時(shí)。在這段時(shí)間內(nèi),用戶可以使用令牌來(lái)訪問(wèn)受保護(hù)的資源。

2、定期檢查

前端應(yīng)用程序在用戶活動(dòng)期間定期檢查令牌的有效性。通常通過(guò)輪詢或心跳機(jī)制實(shí)現(xiàn),即定期向服務(wù)器發(fā)送請(qǐng)求,以驗(yàn)證令牌的有效性。

3、令牌刷新

如果服務(wù)器指示令牌已過(guò)期,前端應(yīng)用程序立即使用refreshToken向身份驗(yàn)證服務(wù)器發(fā)送新請(qǐng)求,以獲取新的訪問(wèn)令牌。無(wú)縫過(guò)渡:在接收到新令牌后,前端應(yīng)用程序會(huì)更新本地存儲(chǔ)的令牌,并繼續(xù)以前的操作,完全不受影響。

4、示例

下面是一個(gè)簡(jiǎn)單的示例,演示如何在前端實(shí)現(xiàn)無(wú)縫刷新令牌:

令牌過(guò)期:假設(shè)服務(wù)器為每個(gè)令牌設(shè)置了30分鐘的過(guò)期時(shí)間。

定期檢查:前端應(yīng)用程序每5分鐘向服務(wù)器發(fā)送一次請(qǐng)求,檢查當(dāng)前令牌的有效性。

// 使用setInterval定期發(fā)送心跳請(qǐng)求
setInterval(() => {
  checkTokenValidity();
}, 5 * 60 * 1000); // 5 分鐘

檢查令牌有效性:前端應(yīng)用程序向服務(wù)器發(fā)送心跳請(qǐng)求以驗(yàn)證令牌的有效性。

async function checkTokenValidity() {
  try {
    const response = await fetch('/api/heartbeat', {
      headers: {
        Authorization: `Bearer ${localStorage.getItem('token')}`
      }
    });

    if (!response.ok) {
      // Token expired, initiate token refresh
      refreshToken();
    }
  } catch (error) {
    // Handle errors
    console.error('Error checking token validity:', error);
  }
}

令牌刷新:如果令牌過(guò)期了,前端應(yīng)用程序會(huì)向身份驗(yàn)證服務(wù)器發(fā)送請(qǐng)求,以獲取一個(gè)新的訪問(wèn)令牌。

async function refreshToken() {
  try {
    const response = await fetch('/api/auth/refresh', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        refreshToken: localStorage.getItem('refreshToken')
      })
    });

    if (response.ok) {
      const data = await response.json();
      // 更新本地存儲(chǔ)的令牌
      localStorage.setItem('accessToken', data.accessToken);
    } else {
      // 處理令牌刷新失敗
      console.error('Failed to refresh token:', response.status);
    }
  } catch (error) {
    // 處理錯(cuò)誤
    console.error('Error refreshing token:', error);
  }
}

在這個(gè)例子中,前端應(yīng)用程序通過(guò)定期檢查令牌的有效性并在需要時(shí)發(fā)起刷新,從而無(wú)縫刷新令牌,確保了用戶體驗(yàn)的流暢性。需要注意的是,出于安全原因,令牌刷新也應(yīng)該有一個(gè)過(guò)期時(shí)間,并且在過(guò)期后用戶可能需要重新登錄。

二、在令牌刷新過(guò)程中處理請(qǐng)求

如果在令牌刷新進(jìn)行中并且新令牌尚未到達(dá)時(shí)發(fā)送額外的請(qǐng)求,可能會(huì)遇到以下這種情況:

如果服務(wù)器檢測(cè)到一個(gè)過(guò)期的令牌,可能會(huì)返回401未經(jīng)授權(quán)或類似的錯(cuò)誤狀態(tài)。在這種情況下,你需要捕獲這些錯(cuò)誤并在捕獲到錯(cuò)誤時(shí)嘗試使用新令牌重新發(fā)送請(qǐng)求。

為處理這些情況,可以采取以下策略:

1、錯(cuò)誤處理

確保你的應(yīng)用能夠捕獲和處理 401 Unauthorized 或相關(guān)的錯(cuò)誤。捕獲這些錯(cuò)誤后,嘗試使用新令牌重新發(fā)送請(qǐng)求。

2、請(qǐng)求重試機(jī)制

實(shí)現(xiàn)一個(gè)請(qǐng)求重試機(jī)制,自動(dòng)或手動(dòng)重新嘗試使用新令牌的失敗請(qǐng)求。你可以使用指數(shù)退避策略來(lái)避免頻繁的重試和減少服務(wù)器負(fù)載。

3、狀態(tài)管理

在令牌刷新期間,將應(yīng)用程序狀態(tài)設(shè)置為“刷新令牌”,并防止新請(qǐng)求,直到獲得新令牌為止。這可以防止使用無(wú)效令牌發(fā)送更多的請(qǐng)求。

4、請(qǐng)求排隊(duì)

在令牌過(guò)期后,將請(qǐng)求排隊(duì),等待獲得新令牌后再逐個(gè)發(fā)送請(qǐng)求??梢允褂肞romise.all或其他異步處理技術(shù)來(lái)實(shí)現(xiàn)這一點(diǎn)。

5、前端通知

在令牌過(guò)期后,在前端顯示通知,告知用戶有關(guān)正在進(jìn)行的令牌刷新過(guò)程以及需要等待或有可能重新登錄的需要。

以下是一個(gè)簡(jiǎn)化的代碼示例,演示了在捕獲到401錯(cuò)誤后如何使用新令牌重新發(fā)送請(qǐng)求。

假設(shè)這是你的API請(qǐng)求函數(shù):

async function apiRequest(url, token) {
  try {
    const response = await fetch(url, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    });

    if (!response.ok) {
      throw new Error(`Request failed with status ${response.status}`);
    }

    return response.json();
  } catch (error) {
    if (error.message.includes('401') && newToken) {
      // 嘗試使用新令牌重新發(fā)送請(qǐng)求
      return apiRequest(url, newToken);
    }
    throw error;
  }
}

// 假設(shè)這是你的 token 刷新功能
let newToken = null; // 用于存儲(chǔ)新令牌的變量

async function refreshToken() {
  try {
    const response = await fetch('/api/auth/refresh', {
      // ... 發(fā)送刷新請(qǐng)求的代碼 ...
    });

    if (response.ok) {
      const data = await response.json();
      newToken = data.token;
    }
  } catch (error) {
    // 處理錯(cuò)誤
  }
}

// 當(dāng)令牌到期時(shí)調(diào)用此函數(shù)
async function handleTokenExpiration() {
  try {
    // 嘗試刷新令牌
    await refreshToken();

    // 假設(shè)這是之前因令牌過(guò)期而失敗的請(qǐng)求的數(shù)組
    const failedRequests = [/* ... */];

    // 使用新令牌重新發(fā)送請(qǐng)求
    for (const request of failedRequests) {
      try {
        const response = await apiRequest(request.url, newToken);
        // 處理響應(yīng)或更新應(yīng)用程序狀態(tài)
      } catch (error) {
        // 處理請(qǐng)求重新發(fā)送期間的錯(cuò)誤
      }
    }
  } catch (error) {
    // 處理令牌刷新或請(qǐng)求重新發(fā)送期間的錯(cuò)誤
  }
}

在這個(gè)示例中,apiRequest函數(shù)檢查 401 錯(cuò)誤,并在有新令牌時(shí)嘗試重新發(fā)送請(qǐng)求。handleTokenExpiration函數(shù)通過(guò)刷新令牌并使用新令牌重新發(fā)送先前失敗的請(qǐng)求來(lái)處理令牌過(guò)期問(wèn)題。

三、排隊(duì)請(qǐng)求

請(qǐng)求排隊(duì)的實(shí)現(xiàn)依賴于使用隊(duì)列數(shù)據(jù)結(jié)構(gòu)來(lái)管理待處理請(qǐng)求。當(dāng)由于某些條件(例如,令牌過(guò)期)需要延遲處理請(qǐng)求時(shí),請(qǐng)求將被添加到隊(duì)列中,等待條件滿足(例如,獲取新令牌)后再進(jìn)行處理。

下面是一個(gè)簡(jiǎn)單的示例,演示了如何實(shí)現(xiàn)請(qǐng)求排隊(duì):

1、創(chuàng)建一個(gè)請(qǐng)求隊(duì)列

首先,你需要一個(gè)隊(duì)列來(lái)存儲(chǔ)待處理的請(qǐng)求。這個(gè)隊(duì)列可以是一個(gè)數(shù)組,內(nèi)存中的鏈表,或者使用現(xiàn)有的隊(duì)列庫(kù)(例如JavaScript中的Array.prototype.queue或queue-promise)。

let requestQueue = []; // 使用數(shù)組作為簡(jiǎn)單的隊(duì)列實(shí)現(xiàn)

2、排隊(duì)操作

當(dāng)請(qǐng)求需要延遲時(shí),請(qǐng)將其添加到隊(duì)列的末尾。

function enqueueRequest(request) {
  requestQueue.push(request);
}

3、出隊(duì)操作

當(dāng)滿足條件時(shí)(例如,獲取新令牌),將請(qǐng)求從隊(duì)列前端出隊(duì)進(jìn)行處理,并重復(fù)直到隊(duì)列為空。

async function dequeueAndProcessRequests() {
  while (requestQueue.length > 0) {
    const request = requestQueue.shift(); // 從隊(duì)列前面撤回請(qǐng)求
    try {
      const response = await processRequest(request); // 處理該請(qǐng)求
      // 處理響應(yīng)或更新應(yīng)用程序狀態(tài)
    } catch (error) {
      // 處理請(qǐng)求處理期間的錯(cuò)誤
      console.error('Error processing request:', error);
    }
  }

4、處理請(qǐng)求

該 processRequest 函數(shù)處理實(shí)際的請(qǐng)求處理邏輯,例如發(fā)送 HTTP 請(qǐng)求或更新 UI。

async function processRequest(request) {
  // 實(shí)際請(qǐng)求處理邏輯,例如發(fā)送HTTP請(qǐng)求
  const response = await fetch(request.url, {
    headers: {
      Authorization: `Bearer ${newToken}` // 使用新的 token
    }
  });
  return response.json(); // 返回處理結(jié)果
}

5、使用示例

當(dāng)令牌過(guò)期時(shí),將需要延遲的請(qǐng)求排隊(duì),然后嘗試刷新令牌。獲得新令牌后,將請(qǐng)求從隊(duì)列中出列并處理它們。

// 假設(shè)這是由于令牌過(guò)期而需要延遲的請(qǐng)求
const delayedRequest = { url: '/api/data' };

// 將請(qǐng)求排隊(duì)
enqueueRequest(delayedRequest);

// 嘗試刷新令牌
await refreshToken();

// 處理隊(duì)列中的請(qǐng)求
await dequeueAndProcessRequests();


責(zé)任編輯:華軒 來(lái)源: 程序員Sunday
相關(guān)推薦

2024-09-02 10:46:57

2024-07-11 10:38:02

2025-04-03 10:17:23

2025-06-23 04:00:00

接口SpringToken

2022-09-28 12:39:46

axios攔截器

2009-09-09 08:39:27

Windows 7兼容性

2011-09-02 09:49:29

JQuery圖片滾動(dòng)

2023-08-23 16:50:43

云計(jì)算數(shù)字化轉(zhuǎn)型

2015-01-26 14:08:37

USP服務(wù)器數(shù)據(jù)中心

2011-05-05 14:52:10

無(wú)縫拼接拼接大屏幕

2013-11-22 10:16:06

NetApp集群模式NetApp存儲(chǔ)

2025-03-14 09:02:03

大模型AI技術(shù)

2014-06-24 11:46:22

2016-12-08 19:13:22

電子簽約上上簽金山WPS

2023-02-28 08:57:06

Spring上下線緩存

2024-05-20 08:50:00

模型神經(jīng)網(wǎng)絡(luò)

2015-07-30 22:59:32

華為公有云/云計(jì)算

2010-04-13 13:53:33

詹睿妮英特爾IDF

2021-04-02 14:23:12

WiFi網(wǎng)絡(luò)技術(shù)

2021-03-31 21:20:15

WiFi網(wǎng)絡(luò)漫游
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)