下次遇到401别再说你不会解决了!!
一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
有两种解决方案:
我这边主要是针对 react 项目来处理的,vue 的逻辑也差不多。
方法1:
此方法大多用于后台管理类型的,因为用的大部分都是自己人,不是很在意用户体验。 基本的步骤如下:
- 响应拦截中拦截
401信息 - 判断有无
token - 提示用户身份认证过期
- 强制跳转至登录页面
代码如下:
// 添加响应拦截器
instance.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response
},
function (error) {
// 对响应错误做点什么
// 在这边有一个特殊情况 -
// 如果没有网络的话,直接去 response 里面是空的,下边的.status就会报错
// 所以这里需要再加一个判断
if (!error.response) {
Toast.show({icon:file, message: '网络异常'})
return Promise.reject(error)
}
// 判断 状态码
if (error.response.status === 401) {
// 如果 === 401,说明用户访问需要登录才可以访问的页面 或者 token过期了
// 判断有没有 token
// 如果没有 token
if (!token) {
// 1. 提示用户
return Toast.show({icon:file, message: '请先进行登录'})
// 2. 跳转至登录页面
history.push('/login')
} else {
// 如果有 token ,但是过期了
// 1. 提示用户
Toast.show({icon:file, message: '身份认证过期,请重新登录'})
// 2. 清除 token 信息
removeToken()
// 3. 退回到登录页面
history.push('/login')
}
}
return Promise.reject(error)
}
)
方法2(双token):
顾名思义,就是有两个 token。
这个方法一般用于C端,更加在意用户体验,用户体验更好。
- 响应拦截中拦截 401 信息
- 判断有无
token - 判断有没有
refresh-token - 提示用户身份认证过期
- 使用
refresh-token重新发起请求获取新的token,然后替换token我这边有一张图,可以帮助大家更直观的了解双token的执行过程。具体的代码如下:
/ 添加响应拦截器
instance.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response
},
async function (error) {
// 对响应错误做点什么
// 这个是没有网络的情况
if (!error.response) {
Toast.show({icon:file, message: '网络异常'})
return Promise.reject(error)
}
const { refresh_token } = getToken()
// 这个是 token 过期 或者访问需要权限的页面
if (error.response.status === 401) {
// 说明 token 过期
// 判断 有没有 refresh_token
if (!refresh_token) {
// 没有 refresh_token,重新登录
history.push({
pathname: '/login',
state: { from: history.location.pathname }
})
return Promise.reject(error)
}
try {
// 如果有 refresh_token, 就发一个新的请求,
// 带上这个 refresh_token,来获取一个新的 token
// 这里的接口是后端定义的特殊接口
const res = await axios.put(baseURL + 'authorizations', null, {
headers: {
Authorization: 'bearer ' + refresh_token
}
})
const newToken = { token: res.data.data.token, refresh_token }
// 然后把接收的这个新的token,重新设置一下
setToken(newToken)
store.dispatch({
type: 'login/token',
payload: newToken
})
// 重发一次请求
// resError 的 config 里面是失败的请求的信息,可以通过 instance 重新发一次请求
return instance(error.config)
} catch (err) {
// 这里是有token,但是token 过期了,也需要重新回退到登录页面
// 提示一下用户
Toast.show({icon:file, message: '身份认证过期,请重新登录'})
history.push({
pathname: '/login',
state: { from: history.location.pathname }
})
return Promise.reject(error)
}
}
return Promise.reject(error)
}
)
好了,今天的知识分析就到这里,喜欢这篇文章的话给我点个赞鼓励一下呗?