日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

雙token登錄

作者:我年薪百萬 更新時(shí)間: 2023-10-09 編程語言

文章目錄

  • 實(shí)現(xiàn)思路
    • code碼?
    • 相應(yīng)攔截器
  • 為什么用雙token登錄
  • 雙token

實(shí)現(xiàn)思路

  1. 用戶登錄向服務(wù)端發(fā)送賬號(hào)密碼信息,登錄失敗返回客戶端重新填寫并發(fā)送用戶信息;登錄成功服務(wù)端生成accessToken和refreshToken并返給客戶端,客戶端將token存本地。
  2. 當(dāng)客戶端想服務(wù)端發(fā)起請(qǐng)求時(shí),在請(qǐng)求頭攜帶accessToken發(fā)送給服務(wù)端,服務(wù)端驗(yàn)證accessToken是否過期,若未過期則正常請(qǐng)求數(shù)據(jù);若過期,服務(wù)端通過code碼將accessToken失效信息返回給客戶端。
  3. 客戶端在響應(yīng)攔截器中添加攔截判斷,若返回accessToken失效信息,則在請(qǐng)求頭攜帶refreshToken ,重新發(fā)起請(qǐng)求,獲取新的accessToken。
  4. 服務(wù)端驗(yàn)證 refreshToken 是否失效。若未過期,則重新生成accessToken返給客戶端;若過期,服務(wù)端通過code碼將refreshToken 失效信息返回給客戶端。
  5. 客戶端在響應(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è)主要目的:

  1. 處理響應(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)換。

  2. 全局錯(cuò)誤處理: 響應(yīng)攔截器可以用來全局處理錯(cuò)誤。如果服務(wù)器返回了一個(gè)錯(cuò)誤響應(yīng)(例如 404 Not Found 或 500 Internal Server Error),響應(yīng)攔截器可以捕獲這些錯(cuò)誤并采取適當(dāng)?shù)拇胧顼@示錯(cuò)誤消息或執(zhí)行其他操作。

  3. Token 刷新: 在前文提到的身份驗(yàn)證和令牌管理方案中,響應(yīng)攔截器可以用于檢查令牌的有效性,如果令牌過期,它可以自動(dòng)請(qǐng)求新的令牌,并重新發(fā)送之前的請(qǐng)求。

  4. 數(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登錄

  1. 一句話概括就是提高系統(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)的安全性。

  2. 減少令牌濫用的風(fēng)險(xiǎn): AccessToken通常用于訪問資源,而RefreshToken用于獲取新的AccessToken。將這兩個(gè)令牌分開有助于降低AccessToken被濫用的風(fēng)險(xiǎn)。即使AccessToken被泄露,攻擊者仍然需要RefreshToken才能獲取新的AccessToken,而RefreshToken通常需要更高的安全性保護(hù)。

  3. 減少頻繁的登錄需求: AccessToken的較短有效期意味著用戶需要更頻繁地重新登錄。但使用RefreshToken,用戶可以在不頻繁輸入用戶名和密碼的情況下獲取新的AccessToken,從而提高了用戶體驗(yàn)。

  4. 支持長(zhǎng)時(shí)間登錄: RefreshToken的較長(zhǎng)有效期允許用戶保持登錄狀態(tài),而無需頻繁重新登錄。這對(duì)于應(yīng)用程序需要長(zhǎng)時(shí)間會(huì)話的情況(如電子郵件或社交媒體應(yīng)用)非常有用。

  5. 粒度控制: 雙令牌機(jī)制允許應(yīng)用程序?qū)ccessToken和RefreshToken的有效期進(jìn)行不同的配置。AccessToken可以設(shè)置為較短的有效期,以提高安全性,而RefreshToken可以設(shè)置為較長(zhǎng)的有效期,以提高用戶體驗(yàn)。

  6. 降低對(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):

  1. 有效期較短: 短期令牌的特點(diǎn)是其有效期相對(duì)較短,通常只有幾分鐘到數(shù)小時(shí)不等。

  2. 用途: 短期令牌通常用于執(zhí)行短期任務(wù),如一次性訪問資源或進(jìn)行敏感操作。它們通常用于一次性的身份驗(yàn)證和授權(quán),隨后會(huì)自動(dòng)失效。

  3. 安全性: 由于有效期短暫,短期令牌通常具有較高的安全性,因?yàn)樗鼈兒芸炀蜁?huì)自動(dòng)過期,從而降低了濫用的風(fēng)險(xiǎn)。

示例: 一次性登錄令牌、短期會(huì)話令牌等。

長(zhǎng)期令牌(Long-Term Token):

  1. 有效期較長(zhǎng): 長(zhǎng)期令牌的特點(diǎn)是其有效期相對(duì)較長(zhǎng),通常可以維持幾天、幾周甚至更長(zhǎng)的時(shí)間。

  2. 用途: 長(zhǎng)期令牌通常用于維持用戶的持久登錄狀態(tài),以便在較長(zhǎng)時(shí)間內(nèi)免除用戶頻繁登錄的需求。它們通常用于記住登錄狀態(tài),例如保持登錄的用戶會(huì)話。

  3. 安全性: 由于有效期較長(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

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新