处理token过期的问题,无感知刷新token 您所在的位置:网站首页 登陆token过期 处理token过期的问题,无感知刷新token

处理token过期的问题,无感知刷新token

2024-07-07 21:34| 来源: 网络整理| 查看: 265

401错误的场景

有如下两种情况会出现401错误:

未登陆用户做一些需要权限才能做的操作,代码会报出401错误。这种情况下,应该让用户回到登陆页。登录用户的token过期了

整体目标是:通过axios响应拦截器来处理401问题。

理解token过期

登陆成功之后,接口会返回一个token值,这个值在后续请求时通过请求头时带上(就像是开门钥匙)。但是,这个值一般会有有效期(具体是多长,是由后端决定),假如在我这里有效期是2小时。

如果你上午8点登陆成功,到了10:01分,则token就会失效,再去发请求时,就会报401错误。

refresh_token和token的作用

当用户登陆成功之后,返回的token中有两个值,说明如下: 在这里插入图片描述

token: 作用:在访问一些接口时,需要传入token,就是它。有效期:2小时(安全)。 refresh_token 作用: 当token的有效期过了之后,可以使用它去请求一个特殊接口(这个接口也是后端指定的,明确需要传入refresh_token),并返回一个新的token回来(有效期还是2小时),以替换过期的那个token。有效期:14天。(最理想的情况下,一次登陆可以持续14天。) 响应拦截器功能

axios中提供了响应拦截器功能:所有从后端回来的响应都会集中进入响应拦截器中。所以,我们可以在响应拦截器中去写代码来统一解决。 在这里插入图片描述 request的响应拦截器中:

对于某次请求A,如果是401错误 (2) 有refresh_token,用refresh_token去请求回新的token (3) 新token请求成功 (4) 更新本地token (5)再发一次请求A (6) 新token请求失败 携带请求地址,跳转到登陆页 没有refresh_token,说明没有登陆 携带请求地址,跳转到登陆页 封装独立的history

src/utils/history

import { createBrowserHistory } from 'history' const history = createBrowserHistory() export default history

App.tsx

import history from '@/utils/history' function App () { return ( // 对响应数据做点什么 return response }, async function (error: AxiosError // 对响应错误做点什么 // console.dir(error) // 1. 处理网络异常状况 // 如果请求延迟,response为undefined if (!error.response) { Toast.show('网络异常') return Promise.reject(error) } // 2. 返回401(token过期)处理 if (error.response.status !== 401) { Toast.show('操作异常') return Promise.reject(error) } if (error.response.status === 401) { // 2.1 获取refresh_token, 发送请求,获取最新的token const { refresh_token } = getToken() // 从本地中获取refresh_token if (refresh_token) { try { // 发请求重新获取token const res = await axios.put(baseURL + 'authorizations', null, { headers: { Authorization: `Bearer ${refresh_token}` } }) // 2.2 保存到redux store.dispatch( savaToken({ token: res.data.data.token, refresh_token }) ) // 2.3 这个时候已经有token了,重新发请求 return instance(error.config) } catch (error) { // 如果使用refresh_token获取token的请求都失败了,就直接跳转到login history.replace('/login', { from: location.pathname }) // 清空redux中的所有token store.dispatch(savaToken({ token: '', refresh_token: '' })) // 将错误抛出 return Promise.reject(error) } } else { // 2.4 没有refresh_token 跳转到login,并携带当前页面的地址,支持回跳 history.replace('/login', { from: location.pathname }) } // 2.5 清除 token 和 refresh_token 相关的数据 store.dispatch(savaToken({ token: '', refresh_token: '' })) // 2.6 抛出错误 return Promise.reject(error) } return Promise.reject(error) } )


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有