最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

VUE前端實現token的無感刷新方式

 更新時間:2023年11月18日 09:09:23   作者:老電影故事  
這篇文章主要介紹了VUE前端實現token的無感刷新方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

前言

說實話,這個其實沒啥好講的,要說有復雜度的話,也主要是在后端。

實現token無感刷新對于前端來說是一項十分常用的技術,其本質都是為了優(yōu)化用戶體驗,當token過期時不需要用戶調回登錄頁重新登錄,而是當token失效時,進行攔截,發(fā)送刷新token的請求,獲取最新的token進行覆蓋,讓用戶感受不到token已過期。

token刷新的方案

方案一:后端返回過期時間,前端判斷token過期時間,去調用刷新token的接口

缺點:需要后端提供一個token過期時間的字段;使用本地時間判斷,若本地時間被修改,本地時間比服務器時間慢,攔截會失敗。

方案二:寫個定時器,定時刷新token接口

缺點:浪費資源,消耗性能,不建議采用

方案三:在響應攔截器中攔截,判斷token返回過期后,調用刷新token接口(?推薦使用)

具體思路

token失效后接口返回401

有感刷新: 清除token,強制跳轉回登錄頁,有感知的重新登錄拿到新token替換到本地,體驗不好

無感刷新: 使用登錄時保存的refresh_token調用另一個接口,換回新的token值,替換到本地,再次完成本次未完成的請求(用戶無感知)

具體步驟:

1、首次登錄的時候會獲取到兩個token, 一個是平時請求接口正常使用的token(過期時間短),另一個是專門用于刷新的refresh_token(過期時間一般比較長),登陸時都存起來 localStorage.setItem(‘refresh_token’,xxx) localStorage.setItem(‘token’, xxx)

2、在響應攔截器中對401狀態(tài)碼引入刷新token的api方法調用

3、替換保存本地新的token

4、headers替換新的token

5、axios再次發(fā)起未完成的請求,返回promise對象到最開始發(fā)起請求的頁面

6、如果refresh_token也過期了,那就判斷是否過期,過期了就清除localstorage跳轉回登錄頁面

登陸時拿到的后端數據:

存起來

refreshToken.js

import request from './request

export function refreshToken() {
	const resp = request.get('/refresh_token', {
		headers: {
			token: `${refresh_token}`
		},
		__isRefreshToken: true
	})
	// return resp.code === 0 // 等于0表示刷新token成功
}

export function isRefreshRequest(config) {
	return !!config.__isRefreshToken //兩個取反,變成boolean
}

request.js

import axios from 'axios'
import { refreshToken, isRefreshRequest } form './refreshToken.js'

// 創(chuàng)建axios實例
const service = axios.create({
  // baseURL: '',// 所有的請求地址前綴部分
  timeout: 25000, // 請求超時時間(毫秒)
  withCredentials: true// 異步請求攜帶cookie
})

// 請求攔截器
service.interceptors.request.use((config: any) => {
	...
}, error => {
	...
})

// 響應攔截器
service.interceptors.response.use((response: any) => {
	let res = response.data
	if (res.code == '401' && !isRefreshRequest(res.config)){ // 如果沒有權限且不是刷新token的請求
		// 刷新token
		try {
			const res = await refreshToken()
			// 保存新的token
			localStorage.setItem('token', res.data.token)
			// 有新token后再重新請求
			response.config.headers.token = localStorage.getItem('token') // 新token
			const resp = await service.request(response.config)
			return resp.data
			// return service(response.config)
		}catch {
			localStorage.clear() // 清除token
			router.replace('/login') // 跳轉到登錄頁
		}
	}
}, error => {
	...
	console.log('error', error)
	return Promise.reject(error)
})

問題一:如何防止多次刷新token

為了防止多次刷新token,可以通過一個變量isRefreshing 去控制是否在刷新token的狀態(tài)

request.js

import axios from 'axios'
import { refreshToken, isRefreshRequest } form './refreshToken.js'

// 創(chuàng)建axios實例
const service = axios.create({
  // baseURL: '',// 所有的請求地址前綴部分
  timeout: 25000, // 請求超時時間(毫秒)
  withCredentials: true// 異步請求攜帶cookie
})

// 請求攔截器
service.interceptors.request.use((config: any) => {
	...
}, error => {
	...
})

// 響應攔截器
service.interceptors.response.use((response: any) => {
	let res = response.data
	let isRefreshing = false
	if (res.code == '401' && ! isRefreshRequest(res.config)){ // 如果沒有權限且不是刷新token的請求
		if (!isRefreshing) {
			isRefreshing = true
			// 刷新token
			try {
				const res = await refreshToken()
				// 保存新的token
				localStorage.setItem('token', res.data.token)
				// 有新token后再重新請求
				response.config.headers.token = localStorage.getItem('token') // 新token
				const resp = await service.request(response.config)
				return resp.data
				// return service(response.config)
			}catch {
				localStorage.clear() // 清除token
				router.replace('/login') // 跳轉到登錄頁
			}
			isRefreshing = false
		}
	}
}, error => {
	...
	console.log('error', error)
	return Promise.reject(error)
})

問題二:同時發(fā)起兩個或者兩個以上的請求時,怎么刷新token

當第二個過期的請求進來,token正在刷新,我們先將這個請求存到一個數組隊列中,想辦法讓這個請求處于等待中,一直等到刷新token后再逐個重試清空請求隊列。

那么如何做到讓這個請求處于等待中呢?

為了解決這個問題,我們得借助Promise。將請求存進隊列中后,同時返回一個Promise,讓這個Promise一直處于Pending狀態(tài)(即不調用resolve),此時這個請求就會一直等啊等,只要我們不執(zhí)行resolve,這個請求就會一直在等待。當刷新請求的接口返回來后,我們再調用resolve,逐個重試。

request.js

import axios from 'axios'
import { refreshToken, isRefreshRequest } form './refreshToken.js'

// 創(chuàng)建axios實例
const service = axios.create({
  // baseURL: '',// 所有的請求地址前綴部分
  timeout: 25000, // 請求超時時間(毫秒)
  withCredentials: true// 異步請求攜帶cookie
})

// 請求攔截器
service.interceptors.request.use((config: any) => {
	...
}, error => {
	...
})

// 響應攔截器
service.interceptors.response.use((response: any) => {
	let res = response.data
	let isRefreshing = false
	let requests = [] // 請求隊列
	if (res.code == '401' && isRefreshRequest(res.config)){ // 如果沒有權限且不是刷新token的請求
		if (!isRefreshing) {
			isRefreshing = true
			// 刷新token
			try {
				const res = await refreshToken()
				// 保存新的token
				localStorage.setItem('token', res.data.token)
				// 有新token后再重新請求
				response.config.headers.token = localStorage.getItem('token') // 新token
				
				// token 刷新后將數組的方法重新執(zhí)行
		        requests.forEach((cb) => cb(token))
		        requests = [] // 重新請求完清空
		        
				const resp = await service.request(response.config)
				return resp.data
				// return service(response.config)
			}catch {
				localStorage.clear() // 清除token
				router.replace('/login') // 跳轉到登錄頁
			}
			isRefreshing = false
		} else {
			// 返回未執(zhí)行 resolve 的 Promise
			return new Promise(resolve => {
				// 用函數形式將 resolve 存入,等待刷新后再執(zhí)行
				request.push(token => {
					response.config.headers.token = `${token}`
					resolve(service(response.config))
				})
			})
		}
	}
}, error => {
	...
	console.log('error', error)
	return Promise.reject(error)
})

具體可以學習這個視頻

token無感刷新

參考文檔

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Vue數據更新頁面卻沒有更新的幾種情況以及解決方法

    Vue數據更新頁面卻沒有更新的幾種情況以及解決方法

    我們在開發(fā)過程中會碰到數據更新,但是頁面卻沒有更新的情況,下面這篇文章主要給大家介紹了關于Vue數據更新頁面卻沒有更新的幾種情況以及解決方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • vue cli使用絕對路徑引用圖片問題的解決

    vue cli使用絕對路徑引用圖片問題的解決

    這篇文章主要給大家介紹了關于vue cli使用絕對路徑引用圖片問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。
    2017-12-12
  • Vue Router中應用中間件的方法

    Vue Router中應用中間件的方法

    這篇文章主要介紹了Vue Router中應用中間件的方法,文中講解非常細致,幫助大家更好的理解和學習vue router,感興趣的朋友可以了解下
    2020-08-08
  • 關于Vue中this.$set的正確使用

    關于Vue中this.$set的正確使用

    我們在項目開發(fā)的過程中,經常會遇到這種情況:為data中的某一個對象添加一個屬性,我們該如何解決這個問題呢,下面小編給大家?guī)砹薞ue中this.$set的正確使用,感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • VUE重點問題總結

    VUE重點問題總結

    本篇內容給大家總結了VUE的重要難點,并把代碼做了詳細分享,有興趣的朋友參考學習下。
    2018-03-03
  • vue+element-ui中form輸入框無法輸入問題的解決方法

    vue+element-ui中form輸入框無法輸入問題的解決方法

    很多初次接觸element-ui的同學,在用到element form組件時可能會遇到input框無法輸入文字的問題,下面這篇文章主要給大家介紹了關于vue+element-ui中form輸入框無法輸入問題的解決方法,需要的朋友可以參考下
    2023-04-04
  • VUE實現時間軸播放組件

    VUE實現時間軸播放組件

    這篇文章主要為大家詳細介紹了VUE實現時間軸播放組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 寫一個Vue loading 插件

    寫一個Vue loading 插件

    這篇文章主要介紹了如何寫一個Vue loading 插件,幫助大家更好的理解和學習vue 插件的相關知識,感興趣的朋友可以了解下
    2020-11-11
  • vue使用echarts實現中國地圖和點擊省份進行查看功能

    vue使用echarts實現中國地圖和點擊省份進行查看功能

    這篇文章主要介紹了vue使用echarts實現中國地圖和點擊省份進行查看功能,本文通過實例代碼給大家詳細講解,對vue echarts 中國地圖相關知識感興趣的朋友一起看看吧
    2022-12-12
  • vue-test-utils初使用詳解

    vue-test-utils初使用詳解

    這篇文章主要介紹了vue-test-utils初使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05

最新評論

绥宁县| 望江县| 乌什县| 博乐市| 沭阳县| 锡林郭勒盟| 习水县| 旬邑县| 通城县| 新巴尔虎左旗| 西乌| 南岸区| 东方市| 年辖:市辖区| 东莞市| 盐亭县| 新乐市| 奇台县| 罗甸县| 鄂尔多斯市| 治多县| 昭通市| 凭祥市| 孟州市| 许昌市| 青岛市| 泰安市| 武乡县| 永德县| 丹阳市| 西藏| 若羌县| 桓台县| 榆林市| 南平市| 炉霍县| 许昌市| 基隆市| 富平县| 汶川县| 正镶白旗|