业务背景: Token数据具有一定的时效时间,通常在几个小时,有效时间内无需重新获取,而基于Redux的存储方式又是基于内存的,刷新就会丢失,为了保持持久化,我们需要单独做处理
解决方案:
使用redux+LocalStorage解决,当浏览器被刷新,可以先查看localStorage中是否存储token,如果没有再进行初始化
1.封装存取方法
// 封装存取方法
const TOKENKEY = 'token_key'
function setToken (token) {
return localStorage.setItem(TOKENKEY, token)
}
function getToken () {
return localStorage.getItem(TOKENKEY)
}
function clearToken () {
return localStorage.removeItem(TOKENKEY)
}
export {
setToken,
getToken,
clearToken
}
2、实现持久化逻辑
import { getToken, setToken } from '@/utils'
const userStore = createSlice({
name: 'user',
// 数据
initialState: {
token: getToken() || ''
},
// 同步修改方法
reducers: {
setUserInfo (state, action) {
state.token = action.payload
// 存入本地
setToken(state.token)
}
}
})
3、Axios请求拦截器注入Token
由于很多前端请求每次访问后端接口,都需要进行接口权限判断,所以我们可以通过Axios统一进行token注入,实现了代码复用
// 添加请求拦截器
request.interceptors.request.use(config => {
// if not login add token
const token = getToken()
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
4、使用Token做路由权限控制
import { getToken } from '@/utils'
import { Navigate } from 'react-router-dom'
const AuthRoute = ({ children }) => {
const isToken = getToken()
if (isToken) {
return <>{children}</>
} else {
return <Navigate to="/login" replace />
}
}
export default AuthRoute
import { createBrowserRouter } from 'react-router-dom'
import Login from '@/pages/Login'
import Layout from '@/pages/Layout'
import AuthRoute from '@/components/Auth'
const router = createBrowserRouter([
{
path: '/',
element: <AuthRoute><Layout /></AuthRoute>,
},
{
path: '/login',
element: <Login />,
},
])
export default router