亚洲黄色片在线观看_日韩精品视频中文在线观看_亚洲国产中文字幕在线观看_亚洲高清久久网

    全球動(dòng)態(tài):無(wú)感知刷新Token示例簡(jiǎn)析

    2023-04-06 05:59:38 來(lái)源:腳本之家
    目錄
    引言Token認(rèn)證的原理什么是無(wú)感知刷新Token實(shí)現(xiàn)步驟步驟一:獲取Access Token和Refresh Token步驟二:在請(qǐng)求中攜帶Access Token步驟三:攔截401 Unauthorized響應(yīng)步驟四:服務(wù)器處理Refresh Token請(qǐng)求步驟五:設(shè)置定時(shí)刷新Token安全性考慮

    引言

    在前后端分離的應(yīng)用中,使用Token進(jìn)行認(rèn)證是一種較為常見(jiàn)的方式。但是,由于Token的有效期限制,需要不斷刷新Token,否則會(huì)導(dǎo)致用戶認(rèn)證失敗。為了解決這個(gè)問(wèn)題,可以實(shí)現(xiàn)無(wú)感知刷新Token的功能,本文將介紹如何實(shí)現(xiàn)無(wú)感知刷新Token。

    Token認(rèn)證的原理

    在Web應(yīng)用中,常見(jiàn)的Token認(rèn)證方式有基于Cookie和基于Token的認(rèn)證。基于Cookie的認(rèn)證方式是將認(rèn)證信息保存在Cookie中,每次請(qǐng)求時(shí)將Cookie發(fā)送給服務(wù)器進(jìn)行認(rèn)證;而基于Token的認(rèn)證方式是將認(rèn)證信息保存在Token中,每次請(qǐng)求時(shí)將Token發(fā)送給服務(wù)器進(jìn)行認(rèn)證。

    在基于Token的認(rèn)證方式中,客戶端將認(rèn)證信息保存在Token中,而不是保存在Cookie中。在認(rèn)證成功后,服務(wù)器將生成一個(gè)Access Token和一個(gè)Refresh Token,并將它們返回給客戶端。Access Token用于訪問(wèn)受保護(hù)的API,Refresh Token用于獲取新的Access Token。


    (資料圖片)

    什么是無(wú)感知刷新Token

    無(wú)感知刷新Token是指,在Token過(guò)期之前,系統(tǒng)自動(dòng)使用Refresh Token獲取新的Access Token,從而實(shí)現(xiàn)Token的無(wú)感知刷新,用戶可以無(wú)縫繼續(xù)使用應(yīng)用。

    在實(shí)現(xiàn)無(wú)感知刷新Token的過(guò)程中,需要考慮以下幾個(gè)方面:

    如何判斷Token是否過(guò)期?如何在Token過(guò)期時(shí)自動(dòng)使用Refresh Token獲取新的Access Token?如何處理Refresh Token的安全問(wèn)題?

    下面將介紹如何實(shí)現(xiàn)無(wú)感知刷新Token的具體步驟。

    實(shí)現(xiàn)步驟

    步驟一:獲取Access Token和Refresh Token

    在認(rèn)證成功后,需要將Access Token和Refresh Token發(fā)送給客戶端。Access Token用于訪問(wèn)受保護(hù)的API,Refresh Token用于獲取新的Access Token。可以使用JWT(JSON Web Token)或OAuth2(開(kāi)放授權(quán))等方式實(shí)現(xiàn)認(rèn)證。

    在JWT中,可以使用如下代碼生成Access Token和Refresh Token:

    const accessToken = jwt.sign({userId: "123"}, "ACCESS_TOKEN_SECRET", {expiresIn: "15m"});
    const refreshToken = jwt.sign({userId: "123"}, "REFRESH_TOKEN_SECRET", {expiresIn: "7d"});
    

    步驟二:在請(qǐng)求中攜帶Access Token

    在每個(gè)需要認(rèn)證的API請(qǐng)求中,需要在請(qǐng)求頭中攜帶Access Token,如下所示:

    GET /api/user HTTP/1.1
    Host: example.com
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    

    在前端中,可以使用Axios等庫(kù)設(shè)置請(qǐng)求頭:

    axios.defaults.headers.common["Authorization"] = `Bearer ${accessToken}`;
    

    步驟三:攔截401 Unauthorized響應(yīng)

    在服務(wù)器返回401 Unauthorized響應(yīng)時(shí),說(shuō)明Access Token已經(jīng)過(guò)期,需要使用Refresh Token獲取新的Access Token。可以使用Axios攔截器或Fetch API的中間件實(shí)現(xiàn)攔截。

    在Axios中,可以使用如下代碼實(shí)現(xiàn)攔截器:

    axios.interceptors.response.use(response => {
      return response;
    }, error => {
      const originalRequest = error.config;
      if (error.response.status === 401 && !originalRequest._retry) {
        originalRequest._retry = true; //防止無(wú)限調(diào)用
        return axios.post("/api/refresh_token", {refreshToken})
          .then(response => {
            const { access_token, refresh_token } = response.data;
            localStorage.setItem("access_token", access_token);
            localStorage.setItem("refresh_token", refresh_token);
            axios.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;
            originalRequest.headers.Authorization = `Bearer ${access_token}`;
            return axios(originalRequest);
          });
      }
      return Promise.reject(error);
    });
    

    在Fetch中,可以使用如下代碼實(shí)現(xiàn)中間件:

    function authMiddleware(request) {
      const access_token = localStorage.getItem("access_token");
      if (access_token) {
        request.headers.set("Authorization", `Bearer ${access_token}`);
      }
      return request;
    }
    function tokenRefreshMiddleware(response) {
      if (response.status === 401) {
        const refreshToken = localStorage.getItem("refresh_token");
        return fetch("/api/refresh_token", {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({ refreshToken })
        }).then(response => {
          if (response.ok) {
            return response.json();
          }
          throw new Error("Refresh Token failed");
        }).then(data => {
          localStorage.setItem("access_token", data.access_token);
          localStorage.setItem("refresh_token", data.refresh_token);
          return Promise.resolve("refreshed");
        }).catch(error => {
          localStorage.removeItem("access_token");
          localStorage.removeItem("refresh_token");
          return Promise.reject(error);
        });
      }
      return Promise.resolve("ok");
    }
    fetch("/api/user", {
      method: "GET",
      headers: {
        "Content-Type": "application/json"
      },
      middleware: [authMiddleware, tokenRefreshMiddleware]
    }).then(response => {
      console.log(response);
    }).catch(error => {
      console.error(error);
    });
    

    在上述代碼中,使用Axios或Fetch攔截器攔截401 Unauthorized響應(yīng),如果發(fā)現(xiàn)Access Token已經(jīng)過(guò)期,則發(fā)送Refresh Token請(qǐng)求獲取新的Access Token,并將新的Access Token設(shè)置到請(qǐng)求頭中,重新發(fā)送請(qǐng)求。

    步驟四:服務(wù)器處理Refresh Token請(qǐng)求

    在服務(wù)器端,需要編寫API處理Refresh Token請(qǐng)求,生成新的Access Token,并返回給客戶端。

    在JWT中,可以使用如下代碼生成新的Access Token:

    const accessToken = jwt.sign({userId: "123"}, "ACCESS_TOKEN_SECRET", {expiresIn: "15m"});
    

    在刷新Token時(shí),需要驗(yàn)證Refresh Token的合法性,可以使用如下代碼驗(yàn)證Refresh Token:

    try {
      const payload = jwt.verify(refreshToken, "REFRESH_TOKEN_SECRET");
      const accessToken = jwt.sign({userId: payload.userId}, "ACCESS_TOKEN_SECRET", {expiresIn: "15m"});
      const refreshToken = jwt.sign({userId: payload.userId}, "REFRESH_TOKEN_SECRET", {expiresIn: "7d"});
      res.json({access_token: accessToken, refresh_token: refreshToken});
    } catch (err) {
      res.sendStatus(401);
    }
    

    在上述代碼中,使用JWT的verify方法驗(yàn)證Refresh Token的合法性,如果驗(yàn)證成功,則生成新的Access Token和Refresh Token,并返回給客戶端。

    步驟五:設(shè)置定時(shí)刷新Token

    為了避免Access Token過(guò)期時(shí)間太長(zhǎng),可以設(shè)置定時(shí)刷新Token的功能。可以使用定時(shí)器或Web Workers等方式實(shí)現(xiàn)定時(shí)刷新Token。在每次刷新Token時(shí),需要重新獲取新的Access Token和Refresh Token,并保存到客戶端。

    function refreshToken() {
      const refreshToken = localStorage.getItem("refresh_token");
      axios.post("/api/refresh_token", {refreshToken})
        .then(response => {
          const { access_token, refresh_token } = response.data;
          localStorage.setItem("access_token", access_token);
          localStorage.setItem("refresh_token", refresh_token);
          axios.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;
        })
        .catch(error => {
          console.error(error);
        });
    }
    setInterval(refreshToken, 14 * 60 * 1000); // 每14分鐘刷新Token
    

    在上述代碼中,使用定時(shí)器每14分鐘刷新Token。在刷新Token成功后,將新的Access Token和Refresh Token保存到客戶端,并將新的Access Token設(shè)置到請(qǐng)求頭中。

    安全性考慮

    在實(shí)現(xiàn)無(wú)感知刷新Token的過(guò)程中,需要考慮到Refresh Token的安全性問(wèn)題。因?yàn)镽efresh Token具有長(zhǎng)期的有效期限,一旦Refresh Token被泄露,攻擊者就可以使用Refresh Token獲取新的Access Token,從而繞過(guò)認(rèn)證機(jī)制,訪問(wèn)受保護(hù)的API。

    為了增加Refresh Token的安全性,可以考慮以下幾種措施:

    將Refresh Token保存在HttpOnly Cookie中,可以避免在客戶端被JavaScript獲取;對(duì)Refresh Token進(jìn)行加密或簽名,可以增加其安全性。將Refresh Token保存在后端,前端通過(guò)接口和后端交互,實(shí)現(xiàn)刷新Access Token。

    以上就是無(wú)感知刷新Token的詳細(xì)內(nèi)容,更多關(guān)于無(wú)感知刷新Token的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

    標(biāo)簽:

主站蜘蛛池模板: 日本久久久a级免费| 国产综合免费视频| 亚洲人成网站在线播放2019| 欧美日韩视频在线一区二区观看视频| 国产欧美自拍视频| 蜜桃麻豆91| 日韩中文在线字幕| 国产精品免费观看久久| 精品国产91亚洲一区二区三区www| 日韩中文字幕国产| 亚洲综合在线做性V| 不卡av在线播放| 国产不卡av在线免费观看| 国产日韩欧美在线看| 美女精品久久久| 中文网丁香综合网| 99久久99久久精品国产片| 国产精品视频免费观看www| 国产视频99| 国产精品美女久久久久av福利 | 欧美有码在线观看视频| 久久99国产精品| 国产精品国模在线| 久久精品国产视频| 人妻少妇精品无码专区二区| 性欧美精品一区二区三区在线播放V | 久久这里精品国产99丫e6| 午夜精品久久久久久久久久久久| 丁香六月激情网| 91精品国产综合久久久久久蜜臀 | 久久亚洲成人精品| 久久久久久91| 久久99视频精品v| 国产一区二区在线视频播放| 国产精品一区二区在线| 国语精品免费视频| 国产精品永久免费视频| 国产精品视频久久久| 国产精品福利在线观看网址| 国产成人精品999| 91禁国产网站|