網(wǎng)站首頁 編程語言 正文
文章目錄
- 實(shí)現(xiàn)思路
- code碼?
- 相應(yīng)攔截器
- 為什么用雙token登錄
- 雙token
實(shí)現(xiàn)思路
- 用戶登錄向服務(wù)端發(fā)送賬號(hào)密碼信息,登錄失敗返回客戶端重新填寫并發(fā)送用戶信息;登錄成功服務(wù)端生成accessToken和refreshToken并返給客戶端,客戶端將token存本地。
- 當(dāng)客戶端想服務(wù)端發(fā)起請(qǐng)求時(shí),在請(qǐng)求頭攜帶accessToken發(fā)送給服務(wù)端,服務(wù)端驗(yàn)證accessToken是否過期,若未過期則正常請(qǐng)求數(shù)據(jù);若過期,服務(wù)端通過code碼將accessToken失效信息返回給客戶端。
- 客戶端在響應(yīng)攔截器中添加攔截判斷,若返回accessToken失效信息,則在請(qǐng)求頭攜帶refreshToken ,重新發(fā)起請(qǐng)求,獲取新的accessToken。
- 服務(wù)端驗(yàn)證 refreshToken 是否失效。若未過期,則重新生成accessToken返給客戶端;若過期,服務(wù)端通過code碼將refreshToken 失效信息返回給客戶端。
- 客戶端在響應(yīng)攔截器中添加攔截判斷,若返回refreshToken 失效信息,則提示用戶需要重新登錄,獲取新的雙token。
code碼?
“code 碼” 通常指的是服務(wù)端向客戶端返回的特定狀態(tài)碼或錯(cuò)誤碼,用于表示不同的操作或狀態(tài)。這個(gè) “code 碼” 可以是一個(gè)數(shù)字或字符串,其具體含義會(huì)根據(jù)服務(wù)端和客戶端之間的協(xié)議或約定而定。通常,不同的 “code 碼” 對(duì)應(yīng)不同的操作或情況,以便客戶端能夠根據(jù)這些 “code 碼” 來執(zhí)行不同的處理邏輯。
通常,開發(fā)者會(huì)定義一套自己的狀態(tài)碼或錯(cuò)誤碼,以便更好地管理客戶端與服務(wù)端之間的通信和處理不同的情況。例如:
- 200:表示成功,請(qǐng)求已成功處理。
- 401:表示未授權(quán),通常用于 AccessToken 失效的情況,客戶端需要重新登-錄或刷新 Token。
- 403:表示禁止訪問,通常用于 RefreshToken 失效的情況,客戶端需要重新登錄獲取新的 Token。
- 500:表示服務(wù)器內(nèi)部錯(cuò)誤,請(qǐng)求未成功處理。
相應(yīng)攔截器
相應(yīng)攔截器(Response Interceptor)是前端開發(fā)中進(jìn)場(chǎng)用到的一種機(jī)制,用于攔截和處理從服務(wù)器返回的HTTP響應(yīng)。相應(yīng)攔截器通常用于以下幾個(gè)主要目的:
-
處理響應(yīng)數(shù)據(jù): 響應(yīng)攔截器允許你在數(shù)據(jù)傳遞到應(yīng)用程序之前對(duì)響應(yīng)數(shù)據(jù)進(jìn)行處理。這包括解析響應(yīng)數(shù)據(jù)、格式化數(shù)據(jù)或?qū)?shù)據(jù)進(jìn)行任何必要的轉(zhuǎn)換。
-
全局錯(cuò)誤處理: 響應(yīng)攔截器可以用來全局處理錯(cuò)誤。如果服務(wù)器返回了一個(gè)錯(cuò)誤響應(yīng)(例如 404 Not Found 或 500 Internal Server Error),響應(yīng)攔截器可以捕獲這些錯(cuò)誤并采取適當(dāng)?shù)拇胧顼@示錯(cuò)誤消息或執(zhí)行其他操作。
-
Token 刷新: 在前文提到的身份驗(yàn)證和令牌管理方案中,響應(yīng)攔截器可以用于檢查令牌的有效性,如果令牌過期,它可以自動(dòng)請(qǐng)求新的令牌,并重新發(fā)送之前的請(qǐng)求。
-
數(shù)據(jù)緩存: 響應(yīng)攔截器還可以用于緩存響應(yīng)數(shù)據(jù),以提高應(yīng)用程序的性能和響應(yīng)速度
響應(yīng)攔截器通常與請(qǐng)求攔截器一起使用,前者用于處理服務(wù)器的響應(yīng),后者用于在發(fā)送請(qǐng)求之前對(duì)請(qǐng)求進(jìn)行處理,例如添加身份驗(yàn)證令牌或請(qǐng)求頭。
相應(yīng)攔截器代碼實(shí)例:
import axios from 'axios';
// 創(chuàng)建一個(gè)axios實(shí)例
const instance = axios.create({
baseURL: 'https://api.example.com',
});
// 添加響應(yīng)攔截器
instance.interceptors.response.use(
(response) => {
// 在數(shù)據(jù)傳遞到應(yīng)用程序之前對(duì)響應(yīng)數(shù)據(jù)進(jìn)行處理
const responseData = response.data;
// 可以進(jìn)行數(shù)據(jù)轉(zhuǎn)換或其他操作
return responseData;
},
(error) => {
// 全局錯(cuò)誤處理
// 可以顯示錯(cuò)誤消息或執(zhí)行其他操作
return Promise.reject(error);
}
);
export default instance;
為什么用雙token登錄
-
一句話概括就是提高系統(tǒng)安全性、降低令牌濫用的風(fēng)險(xiǎn)、改善用戶體驗(yàn)
提高安全性: 雙令牌機(jī)制將身份驗(yàn)證令牌(AccessToken)和令牌刷新令牌(RefreshToken)分開存儲(chǔ)和使用。AccessToken通常具有較短的有效期,而RefreshToken具有更長(zhǎng)的有效期。這可以降低潛在攻擊者利用AccessToken的機(jī)會(huì),因?yàn)锳ccessToken過期后需要使用RefreshToken來獲取新的AccessToken。這提高了系統(tǒng)的安全性。 -
減少令牌濫用的風(fēng)險(xiǎn): AccessToken通常用于訪問資源,而RefreshToken用于獲取新的AccessToken。將這兩個(gè)令牌分開有助于降低AccessToken被濫用的風(fēng)險(xiǎn)。即使AccessToken被泄露,攻擊者仍然需要RefreshToken才能獲取新的AccessToken,而RefreshToken通常需要更高的安全性保護(hù)。
-
減少頻繁的登錄需求: AccessToken的較短有效期意味著用戶需要更頻繁地重新登錄。但使用RefreshToken,用戶可以在不頻繁輸入用戶名和密碼的情況下獲取新的AccessToken,從而提高了用戶體驗(yàn)。
-
支持長(zhǎng)時(shí)間登錄: RefreshToken的較長(zhǎng)有效期允許用戶保持登錄狀態(tài),而無需頻繁重新登錄。這對(duì)于應(yīng)用程序需要長(zhǎng)時(shí)間會(huì)話的情況(如電子郵件或社交媒體應(yīng)用)非常有用。
-
粒度控制: 雙令牌機(jī)制允許應(yīng)用程序?qū)ccessToken和RefreshToken的有效期進(jìn)行不同的配置。AccessToken可以設(shè)置為較短的有效期,以提高安全性,而RefreshToken可以設(shè)置為較長(zhǎng)的有效期,以提高用戶體驗(yàn)。
-
降低對(duì)資源服務(wù)器的負(fù)載: 由于AccessToken的有效期較短,資源服務(wù)器(通常是后端服務(wù)器)需要驗(yàn)證AccessToken的有效性。使用RefreshToken可以減少對(duì)資源服務(wù)器的請(qǐng)求次數(shù),因?yàn)锳ccessToken過期后不需要每次都請(qǐng)求資源服務(wù)器進(jìn)行驗(yàn)證,只需使用RefreshToken獲取新的AccessToken即可。
雙token
Access Token:用于獲取訪問資源或執(zhí)行操作的授權(quán),有效期短。客戶端發(fā)送請(qǐng)求時(shí),在請(qǐng)求頭攜帶此accessToken。
Refresh Token:用來驗(yàn)證用戶的身份,刷新accessToken,有效期長(zhǎng)。當(dāng)accessToken過期時(shí),向服務(wù)端傳遞refreshToken來刷新accessToken。
短期令牌(Short-Term Token):
-
有效期較短: 短期令牌的特點(diǎn)是其有效期相對(duì)較短,通常只有幾分鐘到數(shù)小時(shí)不等。
-
用途: 短期令牌通常用于執(zhí)行短期任務(wù),如一次性訪問資源或進(jìn)行敏感操作。它們通常用于一次性的身份驗(yàn)證和授權(quán),隨后會(huì)自動(dòng)失效。
-
安全性: 由于有效期短暫,短期令牌通常具有較高的安全性,因?yàn)樗鼈兒芸炀蜁?huì)自動(dòng)過期,從而降低了濫用的風(fēng)險(xiǎn)。
示例: 一次性登錄令牌、短期會(huì)話令牌等。
長(zhǎng)期令牌(Long-Term Token):
-
有效期較長(zhǎng): 長(zhǎng)期令牌的特點(diǎn)是其有效期相對(duì)較長(zhǎng),通常可以維持幾天、幾周甚至更長(zhǎng)的時(shí)間。
-
用途: 長(zhǎng)期令牌通常用于維持用戶的持久登錄狀態(tài),以便在較長(zhǎng)時(shí)間內(nèi)免除用戶頻繁登錄的需求。它們通常用于記住登錄狀態(tài),例如保持登錄的用戶會(huì)話。
-
安全性: 由于有效期較長(zhǎng),長(zhǎng)期令牌可能會(huì)具有一定的安全風(fēng)險(xiǎn)。因此,需要采取額外的安全措施來保護(hù)長(zhǎng)期令牌,如定期刷新令牌或?qū)⑵浯鎯?chǔ)在安全的地方。
示例: 持久登錄令牌、刷新令牌等。
代碼實(shí)現(xiàn)雙token
setToken.js
// 設(shè)置
export function setToken (tokenKey, token){
return localStorage.setItem(tokenKey,token)
}
// 獲取
export function getToken (tokenKey){
return localStorage.getItem(tokenKey)
}
// 刪除
export function removeToken(tokenKey){
return localStorage.removeItem(tokenKey)
}
request.js
import axios from 'axios';
import router from './router';
import { setToken, getToken, removeToken } from './setToken.js';
// 封裝 baseURL
const request = axios.create({
baseURL: 'http://****',
timeout: 10000, //請(qǐng)求的超時(shí)毫秒數(shù)
contentType: 'application/json',
});
// 獲取refreshToken
let refreshToken = getToken('refreshToken') || "";
// 判斷是否開啟刷新token:不刷新
let isrefreshToken = false;
// 如果沒有refreshToken(沒登錄||過期了),就開啟刷新token
if (!getToken("refreshToken")) {
isrefreshToken = false;
if (!getToken('refreshToken')) {
isrefreshToken = true;
}
}
// 添加請(qǐng)求攔截器
request.interceptors.request.use((config) => {
// 獲取accessToken
let token = getToken('accessToken');
// 如果有token
if (token) {
// 并且token沒過期
if (!isrefreshToken) {
config.headers['x-token'] = getToken('accessToken') || '';
}
}
// 如果有refreshToken
if (refreshToken) {
// 且需要刷新token
if (isrefreshToken) {
config.headers['x-token'] = getToken('refreshToken');
}
}
return config;
}),
(error) => {
return Promise.reject(error);
};
// 添加響應(yīng)攔截器
request.interceptors.response.use((response) => {
// 對(duì)響應(yīng)數(shù)據(jù)做些什么
console.log('響應(yīng)狀態(tài)碼', response.data.code);
let code = response.data.code;
// 還沒有設(shè)置refreshToken請(qǐng)求頭,需要設(shè)置一下再次發(fā)送請(qǐng)求
if (!refreshToken && getToken('refreshToken') != null) {
refreshToken = getToken('refreshToken');
return request(response.config);
}
if (code == 401 || code == 1021) {
//accessToken過期了,需要帶著refreshToken,去換取新的token
refreshToken = getToken('refreshToken');
isrefreshToken = true;
// 相當(dāng)于重新走一遍剛剛的請(qǐng)求
return request(response.config);
}
if (code == 1024) {
setToken('accessToken', response.data.data);
isrefreshToken = false;
return request(response.config);
} else if (code == 1023) {
// 將本地token刪除
removeToken('refreshToken');
removeToken('accessToken');
// 跳轉(zhuǎn)到登錄頁面,重新登錄
router.push('/login');
//返回信息,讓用戶重新登錄
isrefreshToken = true;
alert('登錄已超期,請(qǐng)重新登錄');
}
return response;
}),
(error) => {
return Promise.reject(error);
};
// 向外暴露 request
export default request;
原文鏈接:https://blog.csdn.net/qq_60893085/article/details/133375859
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-08-01 C#串口編程System.IO.Ports.SerialPort類_C#教程
- 2023-04-20 elementUI無線滾動(dòng)+監(jiān)聽滾動(dòng)條觸底
- 2024-01-29 SpringBoot-yml文件的配置與讀取
- 2022-04-26 python?logging多進(jìn)程多線程輸出到同一個(gè)日志文件的實(shí)戰(zhàn)案例_python
- 2021-12-06 React腳手架搭建的學(xué)習(xí)_React
- 2022-11-07 Android?Framework如何實(shí)現(xiàn)Binder_Android
- 2022-09-08 redis?lua限流算法實(shí)現(xiàn)示例_Redis
- 2022-07-06 C語言中#pragma?once的作用_C 語言
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支