日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

引言

在前后端分離的應用中,使用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??梢允褂肑WT(jsON Web Token)或OAuth2(開放授權)等方式實現認證。

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

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

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

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

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

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

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

步驟三:攔截401 Unauthorized響應

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

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

  1. axios.interceptors.response.use(response => {
  2. return response;
  3. }, error => {
  4. const originalRequest = error.config;
  5. if (error.response.status === 401 && !originalRequest._retry) {
  6. originalRequest._retry = true; //防止無限調用
  7. return axios.post('/api/refresh_token', {refreshToken})
  8. .then(response => {
  9. const { access_token, refresh_token } = response.data;
  10. localStorage.setItem('access_token', access_token);
  11. localStorage.setItem('refresh_token', refresh_token);
  12. axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
  13. originalRequest.headers.Authorization = `Bearer ${access_token}`;
  14. return axios(originalRequest);
  15. });
  16. }
  17. return Promise.reject(error);
  18. });

在Fetch中,可以使用如下代碼實現中間件:

  1. function authMiddleware(request) {
  2. const access_token = localStorage.getItem('access_token');
  3. if (access_token) {
  4. request.headers.set('Authorization', `Bearer ${access_token}`);
  5. }
  6. return request;
  7. }
  8. function tokenRefreshMiddleware(response) {
  9. if (response.status === 401) {
  10. const refreshToken = localStorage.getItem('refresh_token');
  11. return fetch('/api/refresh_token', {
  12. method: 'POST',
  13. headers: {
  14. 'Content-Type': 'Application/json'
  15. },
  16. body: JSON.stringify({ refreshToken })
  17. }).then(response => {
  18. if (response.ok) {
  19. return response.json();
  20. }
  21. throw new Error('Refresh Token failed');
  22. }).then(data => {
  23. localStorage.setItem('access_token', data.access_token);
  24. localStorage.setItem('refresh_token', data.refresh_token);
  25. return Promise.resolve('refreshed');
  26. }).catch(error => {
  27. localStorage.removeItem('access_token');
  28. localStorage.removeItem('refresh_token');
  29. return Promise.reject(error);
  30. });
  31. }
  32. return Promise.resolve('ok');
  33. }
  34. fetch('/api/user', {
  35. method: 'GET',
  36. headers: {
  37. 'Content-Type': 'application/json'
  38. },
  39. middleware: [authMiddleware, tokenRefreshMiddleware]
  40. }).then(response => {
  41. console.log(response);
  42. }).catch(error => {
  43. console.error(error);
  44. });

在上述代碼中,使用Axios或Fetch攔截器攔截401 Unauthorized響應,如果發現Access Token已經過期,則發送Refresh Token請求獲取新的Access Token,并將新的Access Token設置到請求頭中,重新發送請求。

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

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

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

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

在刷新Token時,需要驗證Refresh Token的合法性,可以使用如下代碼驗證Refresh Token:

  1. try {
  2. const payload = jwt.verify(refreshToken, 'REFRESH_TOKEN_SECRET');
  3. const accessToken = jwt.sign({userId: payload.userId}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
  4. const refreshToken = jwt.sign({userId: payload.userId}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});
  5. res.json({access_token: accessToken, refresh_token: refreshToken});
  6. } catch (err) {
  7. res.sendStatus(401);
  8. }

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

步驟五:設置定時刷新Token

為了避免Access Token過期時間太長,可以設置定時刷新Token的功能??梢允褂枚〞r器或Web Workers等方式實現定時刷新Token。在每次刷新Token時,需要重新獲取新的Access Token和Refresh Token,并保存到客戶端。

  1. function refreshToken() {
  2. const refreshToken = localStorage.getItem('refresh_token');
  3. axios.post('/api/refresh_token', {refreshToken})
  4. .then(response => {
  5. const { access_token, refresh_token } = response.data;
  6. localStorage.setItem('access_token', access_token);
  7. localStorage.setItem('refresh_token', refresh_token);
  8. axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
  9. })
  10. .catch(error => {
  11. console.error(error);
  12. });
  13. }
  14. 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
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定