广告位联系
返回顶部
分享到

关于401状态码的含义和处理方式

相关技巧 来源:互联网 作者:佚名 发布时间:2022-08-16 17:57:46 人浏览
摘要

401状态码的含义和处理 401状态码的含义 axios向服务器端发送请求时,有两种情况会出现401状态码(unauthorized未授权): 1. 服务端要求传递token信息,而实际发送请求时没有传递。 2. 发送请

401状态码的含义和处理

401状态码的含义

axios向服务器端发送请求时,有两种情况会出现401状态码(unauthorized未授权):

1. 服务端要求传递token信息,而实际发送请求时没有传递。

2. 发送请求时有传递token到达服务器端,但由于时间比较久,这个token在服务器中已经过期了(服务器存储token有效期时间为2个小时)。

总之,服务器端有些api接口要求传递token,token失效或没有传递,就会报401错误。

401状态码的处理

1. 在axios请求拦截器中做token传递操作。

2. 可以这样设置,在axios响应拦截器中判断请求状态如果是401,就强制用户重新登录系统。

第2种情况处理实现:

在axios的响应拦截器中,判断错误码等于401就强制登录(utils/ax.js)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// 引入路由

import router from '@/router'

// 配置响应拦截器

axios.interceptors.response.use(function (response) {

  // 正常响应处理

  return response

}, function (error) {

  // 非正常响应处理(包括401)

  // console.dir(error) // 对象: config request response isAxiosError toJSON

  if (error.response.status === 401) {

    // token失效(token在服务器端已经失效了,2个小时时效)

    // 强制用户重新登录系统,以刷新服务器端的token时效

    router.push('/login')

    // 不要给做错误提示了

    return new Promise(function () {}) // 空的Promise对象,没有机会执行catch,进而不做错误提示了

  }

  // return new Promise((resolve,reject)=>{

  // reject('获得文章失败!')

  // })

  return Promise.reject(error)

})

注意:

1. 路由对象.push(xxx) 可以实现编程式导航。

2. 路由对象:在组件中是 this.$router ,在main.js/ax.js文件中就是router对象(需要import导入)。

模拟服务器端token失效步骤:

1. 删除客户端sessionStorage数据。

2. 暂时屏蔽守卫代码(开发完毕再打开)。

401状态码升级处理

401状态码

axios向服务器端发送请求时有两种情况会出现401状态码(unauthorized未授权):

1. 服务端要求传递token信息,而实际没有传递。

2. 有传递token到达服务器端,但由于时间比较久,这个token在服务器中已经过期了(服务器存储token有效期时间为2个小时)。

总之,服务器端有些api接口要求传递token,token失效或没有传递,就会报401错误。

相关处理

1. 第1种情况,可以在axios请求拦截器中做token传递操作。

2. 第2种情况,之前是这样处理的,在axios响应拦截器中判断请求状态如果是401,就强制用户重新登录系统

这样处理用户体验非常不好,现在做一次升级优化处理。 

服务器端返回两个秘钥信息,它们在服务端都有使用时效:

  • token 有效期2小时。
  • refresh_token 有效期14天,refresh_token用于在token过期后,重新获取并刷新token时效使用的。

针对第2种401状态码处理步骤为:

1. 判断refresh_token是否存在

不存在就直接重新登录。

存在,axios发起请求,带着refresh_token请求服务端,获取新token出来:

成功:对vuex和localStorage进行token信息更新。

失败:清空无效用户信息,直接重新登录。

示例代码1 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

// 响应拦截器 (响应成功:剥离无效数据,响应失败:刷新token)

instance.interceptors.response.use(res => {

  // 将来获取数据:res.data.data 麻烦

  // 想要结果:data 即可

  try {

    return res.data.data

  } catch (e) {

    return res

  }

}, async err => {

  try {

    // 目的:刷新token

    if (err.response && err.response.status === 401) {

    // 未登录  跳转登录页面  阻止程序运行

      const { user } = store.state

      // 如果没有token没登录  如果没有refresh_token无法刷新token

      if (!user.token || !user.refresh_token) {

        router.push('/login')

        return Promise.reject(err)

      }

      // 刷新token,发请求,没有配置的axios,自己配置refresh_token

      const res = await axios({

        url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',

        method: 'put',

        headers: {

          Authorization: `Bearer ${user.refresh_token}`

        }

      })

      // token获取  res.data.data.token

      // 更新 vuex 和 本地 token

      store.commit('setUser', {

        token: res.data.data.token,

        refresh_token: user.refresh_token

      })

      // 继续发送刚才错误的请求

      // instance({之前错误的请求配置})

      // err错误对象 包含(response 响应对象 |config 请求配置)

      return instance(err.config)

    }

  } catch (e) { // exception 异常

    // 刷新token失败

    router.push('/login')

    return Promise.reject(e)

  }

  return Promise.reject(err)

})

演示代码:promise错误处理:

示例代码2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

import store from '@/store' // 引入vuex中的store实例

import router from '@/router' // 引入路由对象实例

……

// 响应拦截器

instance.interceptors.response.use(

  function (response) {

    try {

      // 返回具体有价值的业务数据

      return response.data.data

    } catch (error) {

      return response.data

    }

  },

  async function (error) {

    // 响应有错误,有可能错误状态码为401

    if (error.response && error.response.status === 401) {

      // 定义登录路由对象

      let toPath = {

        name: 'login',

        query: { redirectUrl: router.currentRoute.path }

      } // 跳转对象

      // 如果refresh_token不存在

      if (!store.state.user.refresh_token) {

        router.push(toPath)

        return Promise.reject(error)

      }

      try {

        // 刷新用户token

        // 应该发送一个请求 换取新的token

        // 这里不应该再用instance  因为 instance会再次进入拦截器  用默认的axios

        let result = await axios({

          method: 'put',

          url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',

          headers: {

            Authorization: `Bearer ${store.state.user.refresh_token}`

          }

        })

        // 获取到新token后,就对vuex和localStorage进行更新

        store.commit('updateUser', {

          token: result.data.data.token, // 拿到新的token之后

          refresh_token: store.state.user.refresh_token // 将之前 refresh_token 14天有效期

        })

        return instance(error.config) // 把刚才错误的请求再次发送出去 然后将promise返回

      } catch (err) {

        // 如果错误 表示补救措施也没用了(有可能refresh_token也失效了)

        // 应该跳转到登录页 并且 把废掉的用户信息全都干掉

        store.commit('clearUser') // 所有的用户信息清空

        router.push(toPath) // 跳转到回登录页

        return Promise.reject(err)

      }

    }

    return Promise.reject(error)

  }

)

') // 所有的用户信息清空

        router.push(toPath) // 跳转到回登录页

        return Promise.reject(err)

      }

    }

    return Promise.reject(error)

  }

)


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://blog.csdn.net/jyn15159/article/details/108879988
    Tag :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计