Commit 6614a3f4 by lijiabin

【需求 20331】 feat: 完成token续签功能、用户信息存到storage里面支持持久化处理,避免重复调登录接口

parent 0ca5c7a1
import { defineStore } from 'pinia'
import { loginByCode, loginByEmail } from '@/api/login'
import { loginByCode, loginByEmail, refreshTokenApi } from '@/api/login'
import type { LoginResponseDto } from '@/api/login/types'
/**
* 关于用户的store
*/
export const useUserStore = defineStore('user', () => {
const userInfo = ref(JSON.parse(sessionStorage.getItem('userInfo') || '{}') as LoginResponseDto)
// const token = ref(localStorage.getItem('token') || '')
const token = ref(sessionStorage.getItem('token') || '')
const userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}') as LoginResponseDto)
const token = ref(localStorage.getItem('token') || '')
const refreshToken = ref(localStorage.getItem('refreshToken') || '')
// 获取用户信息
const fetchUserInfo = async () => {
// {
......@@ -41,20 +41,54 @@ export const useUserStore = defineStore('user', () => {
}) => {
const { data } = await loginByCode({ code, isCodeLogin, cutEmail })
console.log(data)
setUserInfoAndToken(data)
}
const getNewToken = async () => {
const { data } = await refreshTokenApi(refreshToken.value)
setUserInfoAndToken(data)
}
const setUserInfoAndToken = async (data: LoginResponseDto) => {
setUserInfo(data)
setToken(data.token)
setRefreshToken(data.refreshToken)
}
const clearAllUserInfo = () => {
userInfo.value = {} as LoginResponseDto
token.value = ''
refreshToken.value = ''
localStorage.removeItem('userInfo')
localStorage.removeItem('token')
localStorage.removeItem('refreshToken')
}
const setUserInfo = (info: LoginResponseDto) => {
userInfo.value = info
// session存一份
sessionStorage.setItem('userInfo', JSON.stringify(info))
localStorage.setItem('userInfo', JSON.stringify(info))
}
const setToken = (str: string) => {
token.value = str
// session存一份
sessionStorage.setItem('token', str)
localStorage.setItem('token', str)
}
const setRefreshToken = (str: string) => {
refreshToken.value = str
localStorage.setItem('refreshToken', str)
}
// window.setToken = (str: string) => {
// setToken(str)
// }
return { userInfo, token, fetchUserInfo, setUserInfo, setToken, getUserInfoByCode }
return {
userInfo,
token,
fetchUserInfo,
setUserInfo,
setToken,
getUserInfoByCode,
refreshToken,
getNewToken,
clearAllUserInfo,
}
})
......@@ -9,7 +9,10 @@ import {
} from './service'
import type { BackendServiceResult, RequestServiceError } from './types'
import { showErrorMsg } from '@/utils/toast'
import type { AxiosError, AxiosResponse } from 'axios'
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import service from './index'
import { useUserStore } from '@/stores/user'
/**
* 后端逻辑code报错处理
......@@ -94,7 +97,14 @@ export function handleRequestError<T>(axiosError: AxiosError<BackendServiceResul
type: 'error',
duration: 0,
})
} else if (error.code === 401) {
// 处理401的
console.log(error, '这里是401么', axiosError)
// 重新发送一遍请求
// service.request(axiosError.config as AxiosRequestConfig)
return handleUnAuthorized(axiosError)
} else {
console.log(error, axiosError, '这里是其他错误么')
showErrorMsg(error)
}
// 鉴权错误
......@@ -111,3 +121,29 @@ function useService404() {
// useUserStroe().loginout()
// router.replace('/login')
}
// 处理401的
let promiseFlashing: Promise<void> | null = null
async function handleUnAuthorized(axiosError: AxiosError) {
const userStore = useUserStore()
if (!promiseFlashing) {
promiseFlashing = userStore.getNewToken()
}
try {
// 捕捉这一个错误
await promiseFlashing
return service.request(axiosError.config as AxiosRequestConfig)
} catch (e) {
console.log(e)
ElMessage({
showClose: true,
message: '重新获取token失败,请关闭标签页,重新打开',
type: 'error',
duration: 0,
})
userStore.clearAllUserInfo()
return Promise.reject(e)
} finally {
promiseFlashing = null
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment