全球動態:無感知刷新Token示例簡析

            2023-04-06 05:59:38 來源:腳本之家
            目錄
            引言Token認證的原理什么是無感知刷新Token實現步驟步驟一:獲取Access Token和Refresh Token步驟二:在請求中攜帶Access Token步驟三:攔截401 Unauthorized響應步驟四:服務器處理Refresh Token請求步驟五:設置定時刷新Token安全性考慮

            引言

            在前后端分離的應用中,使用Token進行認證是一種較為常見的方式。但是,由于Token的有效期限制,需要不斷刷新Token,否則會導致用戶認證失敗。為了解決這個問題,可以實現無感知刷新Token的功能,本文將介紹如何實現無感知刷新Token。

            Token認證的原理

            在Web應用中,常見的Token認證方式有基于Cookie和基于Token的認證。基于Cookie的認證方式是將認證信息保存在Cookie中,每次請求時將Cookie發送給服務器進行認證;而基于Token的認證方式是將認證信息保存在Token中,每次請求時將Token發送給服務器進行認證。

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


            (資料圖片)

            什么是無感知刷新Token

            無感知刷新Token是指,在Token過期之前,系統自動使用Refresh Token獲取新的Access Token,從而實現Token的無感知刷新,用戶可以無縫繼續使用應用。

            在實現無感知刷新Token的過程中,需要考慮以下幾個方面:

            如何判斷Token是否過期?如何在Token過期時自動使用Refresh Token獲取新的Access Token?如何處理Refresh Token的安全問題?

            下面將介紹如何實現無感知刷新Token的具體步驟。

            實現步驟

            步驟一:獲取Access Token和Refresh Token

            在認證成功后,需要將Access Token和Refresh Token發送給客戶端。Access Token用于訪問受保護的API,Refresh Token用于獲取新的Access Token。可以使用JWT(JSON Web Token)或OAuth2(開放授權)等方式實現認證。

            在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"});
            

            步驟二:在請求中攜帶Access Token

            在每個需要認證的API請求中,需要在請求頭中攜帶Access Token,如下所示:

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

            在前端中,可以使用Axios等庫設置請求頭:

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

            步驟三:攔截401 Unauthorized響應

            在服務器返回401 Unauthorized響應時,說明Access Token已經過期,需要使用Refresh Token獲取新的Access Token。可以使用Axios攔截器或Fetch API的中間件實現攔截。

            在Axios中,可以使用如下代碼實現攔截器:

            axios.interceptors.response.use(response => {
              return response;
            }, error => {
              const originalRequest = error.config;
              if (error.response.status === 401 && !originalRequest._retry) {
                originalRequest._retry = true; //防止無限調用
                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中,可以使用如下代碼實現中間件:

            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響應,如果發現Access Token已經過期,則發送Refresh Token請求獲取新的Access Token,并將新的Access Token設置到請求頭中,重新發送請求。

            步驟四:服務器處理Refresh Token請求

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

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

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

            在刷新Token時,需要驗證Refresh Token的合法性,可以使用如下代碼驗證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方法驗證Refresh Token的合法性,如果驗證成功,則生成新的Access Token和Refresh Token,并返回給客戶端。

            步驟五:設置定時刷新Token

            為了避免Access Token過期時間太長,可以設置定時刷新Token的功能。可以使用定時器或Web Workers等方式實現定時刷新Token。在每次刷新Token時,需要重新獲取新的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
            

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

            安全性考慮

            在實現無感知刷新Token的過程中,需要考慮到Refresh Token的安全性問題。因為Refresh Token具有長期的有效期限,一旦Refresh Token被泄露,攻擊者就可以使用Refresh Token獲取新的Access Token,從而繞過認證機制,訪問受保護的API。

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

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

            以上就是無感知刷新Token的詳細內容,更多關于無感知刷新Token的資料請關注腳本之家其它相關文章!

            標簽:

          亚洲毛片不卡av在线播放一区| 亚洲最大黄色网址| 亚洲AV成人影视在线观看| 亚洲二区在线视频| 亚洲精品综合久久中文字幕| 亚洲黄色一级毛片| 78成人精品电影在线播放日韩精品电影一区亚洲 | 7777久久亚洲中文字幕蜜桃| 日韩亚洲AV无码一区二区不卡 | 国产亚洲精品成人AA片新蒲金| 亚洲AV之男人的天堂| 国产亚洲日韩在线a不卡| gogo全球高清大胆亚洲| 亚洲精品天堂成人片?V在线播放| 亚洲国产午夜福利在线播放 | 亚洲熟伦熟女新五十路熟妇| 亚洲国产成人久久一区久久 | 亚洲国产精品激情在线观看| 亚洲精品色婷婷在线影院| 亚洲国产精品一区二区三区在线观看| 亚洲综合综合在线| 亚洲女人影院想要爱| 亚洲视频无码高清在线| 亚洲国产aⅴ成人精品无吗| 国产精品亚洲专区无码不卡| 亚洲精品岛国片在线观看| a级亚洲片精品久久久久久久| 亚洲精品乱码久久久久久蜜桃不卡| 亚洲国产另类久久久精品小说| 久久精品国产精品亚洲蜜月| 久久亚洲精品无码aⅴ大香| 亚洲成a人片在线观看播放| 中文日韩亚洲欧美制服| 亚洲av成人片在线观看| 亚洲伊人成无码综合网| 亚洲成AV人片在线观看ww| 亚洲综合综合在线| 亚洲一日韩欧美中文字幕在线 | 亚洲人成网址在线观看| 亚洲人成伊人成综合网久久| 亚洲人成色99999在线观看|