软件教程 2025年08月6日
0 收藏 0 点赞 236 浏览 5025 个字
摘要 :

文章目录 token 过期处理 token 过期问题 响应拦截器处理token 本文主要讲解关于如何解决token过期的问题,学习token过期了怎么处理相关内容,让我们来一起学习下吧!……




  • token 过期处理
    • token 过期问题
    • 响应拦截器处理token

    本文主要讲解关于如何解决token过期的问题,学习token过期了怎么处理相关内容,让我们来一起学习下吧!

    token过期了怎么办?一般做法是重复第一次获取token的过程(比如登录,扫描授权等) ,这样做的缺点是用户体验不好,每一小时强制登录一次几乎是无法忍受的。那应该怎么办呢?其实这是一个老生常谈的问题,但是最近发现很多人并不清楚,所以今天就一次讲清这个问题!

    token 过期处理

    没有绝对的安全, 所谓的安全处理, 就是提高攻击者攻击的难度, 对他造成了一定的麻烦, 我们这个网站就是安全的! 网站安全性就是高的! 所以: token 必须要有过期时间!

    token 过期问题

    目标: 了解token过期问题的存在, 学习token过期的解决思路

    现象:

    你登陆成功之后,接口会返回一个token值,这个值在后续请求时带上(就像是开门钥匙)。

    但是,这个值一般会有有效期(具体是多长,是由后端决定),在我们的项目中,这个有效期是2小时。

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

    思考:

    1. token需要过期时间吗 ?

      token即是获取受保护资源的凭证,当然必须有过期时间。否则一次登录便可永久使用,认证功能就失去了其意义。非但必须有个过期时间,而且过期时间还不能太长,

      参考各个主流网站的token过期时间,一般1小时左右

      token一旦过期, 一定要处理, 不处理, 用户没法进行一些需要授权页面的使用了

    2. token过期该怎么办?

      token过期,就要重新获取。

      那么重新获取有两种方式,一是重复第一次获取token的过程(比如登录,扫描授权等) ,这样做的缺点是用户体验不好,每一小时强制登录一次几乎是无法忍受的。

      那么还剩第二种方法,那就是主动去刷新token. 主动刷新token的凭证是refresh token,也是加密字符串,并且和token是相关联的。相比可以获取各种资源的token,refresh token的作用仅仅是获取新的token,因此其作用和安全性要求都大为降低,所以其过期时间也可以设置得长一些。

    目标效果 – 保证每一小时, 都是一个不同的token

    第一次请求 9:00 用的是 token1第二次请求 12:00 用的是 token2

    当用户登陆成功之后,返回的token中有两个值,说明如下:如何解决token过期问题,怎么处理?

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

    如何解决token过期问题,怎么处理?

    对于 某次请求A 的响应,如果是401错误

    • 有refresh_token,用refresh_token去请求回新的token
      • 新token请求成功
        • 更新本地token
        • 再发一次请求A
      • 新token请求失败
        • 清空vuex中的token
        • 携带请求地址,跳转到登陆页
    • 没有refresh_token
      • 清空vuex中的token
      • 携带请求地址,跳转到登陆页

    对于一个请求的响应 401, 要这么处理, 对于十个请求的响应 401, 也要这么处理,

    我们可以统一将这个token过期处理放在响应拦截器中

    请求拦截器: 所有的请求, 在真正被发送出去之前, 都会先经过请求拦截器 (可以携带token)

    响应拦截器: 所有的响应, 在真正被(.then.catch await)处理之前, 都会先经过响应拦截器, 可以在这个响应拦截器中统一对响应做判断

    响应拦截器处理token

    目标: 通过 axios 响应拦截器来处理 token 过期的问题

    1. 没有 refresh_token 拦截到登录页, 清除无效的token

    测试: {“token”:”123.123.123″}

    // 添加响应拦截器
    http.interceptors.response.use(function (response) {
      // 对响应数据做点什么 (成功响应) response 就是成功的响应 res
      return response
    }, function (error) {
      // 对响应错误做点什么 (失败响应) 处理401错误
      // console.dir(error)
      if (error.response.status === 401) {
        console.log(\'token过期了, 一小时过去了, 需要通过refresh_token去刷新token\')
        // 获取 refresh_token, 判断是否存在, 存在就去刷新token
        const refreshToken = store.state.tokenInfo.refresh_token
        if (refreshToken) {
          console.log(\'存在refreshToken, 需要进行刷新token操作\')
        } else {
          // 没有refreshToken, 直接去登录, 将来还能跳回来
          // router.currentRoute 指向当前路由信息对象 === 等价于之前页面中用的 this.$route
          // 清除本地token, 跳转登录 (无意义的本地token内容, 要清除)
          store.commit(\'removeToken\')
          router.push({
            path: \'/login\',
            query: {
              backto: router.currentRoute.fullPath
            }
          })
        }
      }
      return Promise.reject(error)
    })
    

    提供清除token的mutation

    // 移出tokenInfo的信息, 恢复成空对象
    removeToken (state) {
      state.tokenInfo = {}
      // 更新到本地, 本地可以清掉token信息
      removeToken()
    },
    
    1. 有 refresh_token 发送请求, 刷新token

    测试操作: 将 token 修改成 xyz, 模拟 token 过期, 而有 refresh_token 发现401, 会自动帮你刷新token

    {\"refresh_token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDYzNTcyODcsInVzZXJfaWQiOjExMDI0OTA1MjI4Mjk3MTc1MDQsInJlZnJlc2giOnRydWV9.2A81gpjxP_wWOjclv0fzSh1wzNm6lNy0iXM5G5l7TQ4\",\"token\":\"xyz\"}

    const refreshToken = store.state.tokenInfo.refresh_token
    if (refreshToken) {
      console.log(\'存在refreshToken, 需要进行刷新token操作\')
      // (1) 发送请求, 进行刷新token操作, 获取新的token
      // 注意: 这边发请求, 不用http实例, 用它会自动在请求前帮你携带token(会覆盖你的refresh_token)
      // 这边, 直接用 axios 发送请求
      const res = await axios({
        method: \'put\',
        url: \'http://ttapi.research.itcast.cn/app/v1_0/authorizations\',
        // 请求头中携带refresh_token信息
        headers: {
          Authorization: `Bearer ${refreshToken}`
        }
      })
      const newToken = res.data.data.token
      // (2) 将新token更新到vuex中
      store.commit(\'setTokenInfo\', {
        refresh_token: refreshToken,
        token: newToken
      })
    } 
    
    1. 刷新token后, 应该重新发送刚才的请求 (让用户刷新token无感知)
    return http(error.config)
    
    1. 那万一 refresh_token 也过期了, 是真正的用户登录过期了 (一定要让用户重新登录的)

    测试: {“refresh_token”:”123.123″,”token”:”123.123.123″} 修改后, 修改的是本地, 记得刷新一下

    从哪拦走的, 就回到哪去

    // 添加响应拦截器
    http.interceptors.response.use(function (response) {
      // 对响应数据做点什么 (成功响应) response 就是成功的响应 res
      return response
    }, async function (error) {
      // 对响应错误做点什么 (失败响应) 处理401错误
      // console.dir(error)
      if (error.response.status === 401) {
        console.log(\'token过期了, 一小时过去了, 需要通过refresh_token去刷新token\')
        // 获取 refresh_token, 判断是否存在, 存在就去刷新token
        const refreshToken = store.state.tokenInfo.refresh_token
        if (refreshToken) {
          try {
            console.log(\'存在refreshToken, 需要进行刷新token操作\')
            // (1) 发送请求, 进行刷新token操作, 获取新的token
            // 注意: 这边发请求, 不用http实例, 用它会自动在请求前帮你携带token(会覆盖你的refresh_token)
            // 这边, 直接用 axios 发送请求
            const res = await axios({
              method: \'put\',
              url: \'http://ttapi.research.itcast.cn/app/v1_0/authorizations\',
              // 请求头中携带refresh_token信息
              headers: {
                Authorization: `Bearer ${refreshToken}`
              }
            })
            const newToken = res.data.data.token
            // (2) 将新token更新到vuex中
            store.commit(\'setTokenInfo\', {
              refresh_token: refreshToken,
              token: newToken
            })
            // (3) 重新发送刚才的请求, http, 自动携带token (携带的是新token)
            //     error.config就是之前用于请求的配置对象, 可以直接给http使用
            return http(error.config)
          } catch {
            // refresh_token 过期了, 跳转到登录页
            // 清除过期的token对象
            store.commit(\'removeToken\')
            // 跳转到登录页, 跳转完, 将来跳回来
            router.push({
              path: \'/login\',
              query: {
                backto: router.currentRoute.fullPath
              }
            })
          }
        } else {
          // 没有refreshToken, 直接去登录, 将来还能跳回来
          // router.currentRoute 指向当前路由信息对象 === 等价于之前页面中用的 this.$route
          // 清除本地token, 跳转登录 (无意义的本地token内容, 要清除)
          store.commit(\'removeToken\')
          router.push({
            path: \'/login\',
            query: {
              backto: router.currentRoute.fullPath
            }
          })
        }
      }
      return Promise.reject(error)
    })
    

    注意点:

    1. 响应拦截器要加在axios实例 http 上。
    2. 用refresh_token请求新token时,要用axios,不要用实例 http (需要: 手动用 refresh_token 请求)
    3. 得到新token之后,再发请求时,要用 http 实例 (用token请求)
    4. 过期的 token 可以用 refresh_token 再次更新获取新token, 但是过期的 refresh_token 就应该从清除了

    以上就是关于如何解决token过期的问题,学习token过期了怎么处理相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6599.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

269
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

107
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

683
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

338
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

843
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号