react 中401问题-整体说明

401错误的场景

  1. 未登陆用户做一些需要权限才能做的操作(例如:关注作者),代码会报出401错误。这种情况下,应该让用户回到登陆页。

  2. 登录用户的token过期了

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

refresh_token和token的作用

  • token:

    • 作用:在访问一些接口时,需要传入token,就是它。

    • 有效期:2小时(安全)。

  • refresh_token

    • 作用: 当token的有效期过了之后,可以使用它去请求一个特殊接口(这个接口也是后端指定的,明确需要传入refresh_token),并返回一个新的token回来(有效期还是2小时),以替换过期的那个token。

    • 有效期:14天。(最理想的情况下,一次登陆可以持续14天。)

401问题-思路-响应拦截器

axios中提供了响应拦截器功能:所有从后端回来的响应都会集中进入响应拦截器中。所以,我们可以在响应拦截器中去写代码来统一解决。react 中401问题-整体说明

 由于这里涉及到非组件内路由跳转,所以需要提前封装独立的history 这里可以看我React 在非组件环境拿到路由信息_捧鲜花的唐老鸭的博客-CSDN博客react 中401问题-整体说明https://blog.csdn.net/weixin_58207509/article/details/121413518?spm=1001.2014.3001.5502

这一篇博客 

核心代码 里面包含(typescript)

/* eslint-disable camelcase */
// axios 封装
// 1. 基地址
// 2. 请求拦截器
// 3. 响应拦截器
// 封装axios
import { Toast } from 'antd-mobile'
import axios, { AxiosError } from 'axios'
import { getToken, hasToken, removeToken, setToken } from './storage'
import history from './history'
import store from '@/store'
import { saveToken } from '@/store/actions/login'
// import store from '@/store'
const baseURL = 'http://geek.itheima.net/v1_0/'
const instance = axios.create({
  baseURL,
  timeout: 5000
})

// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    if (hasToken()) {
      const token = getToken().token
      // 添加到请求头
      config.headers!.Authorization = `Bearer ${token}`
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    return response
  },
  async function (error: AxiosError) {
    if (!error.response) {
      Toast.show('网络异常')
      return Promise.reject(error)
    }
    if (error.response.status !== 401) {
      Toast.show('操作异常')
      return Promise.reject(error)
    }
    if (error.response.status === 401) {
      // 1 获取refresh_token
      const { refresh_token } = getToken()
      // 2  发请求重新获取token
      try {
        const res = await axios.put(baseURL + 'authorizations', null, { headers: { Authorization: `Bearer ${refresh_token}` } })
        // 3 本地 存储token
        setToken({ token: res.data.data.token, refresh_token })
        // 4 redux存储token
        store.dispatch(saveToken({ token: res.data.data.token, refresh_token }))
        // 5 重新之前报错的发请求
        return instance(error.config)
      } catch (err) {
        // 2.2 如果 refresh_token 也过期了 回到登录页 重新登录
        history.push('/login')
        // 2.3 清空token
        removeToken()
        return Promise.reject(err)
      }
    }

    console.log(history)

    // 对响应错误做点什么
    return Promise.reject(error)
  }
)

export default instance

上一篇:Mongodb源代码阅读笔记:Journal机制


下一篇:ConnectionError: Couldn‘t reach https://raw.githubuserc//huggingface/datasets/1.15.1/datasets/squad/