Vue如何优雅处理Token过期并自动续期

 更新时间:2025年07月24日 09:05:33   作者:江城开朗的豌豆  
干了6年前端,和Token斗智斗勇了不知道多少回,本文小编就跟大家聊聊如何优雅处理Token过期,甚至让它自动续期,让用户无感知,有需要的小伙伴可以了解下

大家好,干了6年前端,和Token斗智斗勇了不知道多少回。最烦的就是用户正填着表单呢,突然跳登录页——Token过期了!今天就跟大家聊聊如何优雅处理Token过期,甚至让它自动续期,让用户无感知!

一、Token过期,用户的噩梦

想象一下:

  • 用户填了半小时的报销单,点击提交—— “登录失效,请重新登录”
  • 购物车选了半天,结算时——跳转登录页

血压直接拉满,用户体验直接崩盘!

常见处理方式(但不够优雅)

  • 粗暴型:Token过期直接跳登录页(用户骂娘)
  • 提醒型:弹窗提示“登录已过期”(用户还是得手动操作)
  • 轮询检查型:定时检查Token是否快过期(浪费请求)

但今天我要讲的是更高级的玩法——无感知自动续期

二、Token自动续期方案

1. 方案核心思路

  • 短期Token(Access Token) :用来做日常请求(比如2小时过期)
  • 长期Token(Refresh Token) :用来换新Token(比如7天过期)

流程:

  • 用户登录,拿到 access_token 和 refresh_token
  • access_token 过期后,用 refresh_token 去换新的
  • 如果 refresh_token 也过期了,才让用户重新登录

2. 前端如何实现

(1)Axios 拦截器处理过期

// 请求拦截
axios.interceptors.request.use(config => {
  const accessToken = localStorage.getItem('access_token')
  if (accessToken) {
    config.headers.Authorization = `Bearer ${accessToken}`
  }
  return config
})

// 响应拦截
axios.interceptors.response.use(
  response => response,
  async error => {
    const originalRequest = error.config
    // 如果是401(Token过期)且未重试过
    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true
      try {
        // 用 refresh_token 换新的 access_token
        const res = await axios.post('/refresh-token', {
          refresh_token: localStorage.getItem('refresh_token')
        })
        const { access_token, refresh_token } = res.data
        localStorage.setItem('access_token', access_token)
        localStorage.setItem('refresh_token', refresh_token)
        // 重新发之前的请求
        originalRequest.headers.Authorization = `Bearer ${access_token}`
        return axios(originalRequest)
      } catch (refreshError) {
        // refresh_token 也过期了,跳登录页
        window.location.href = '/login'
      }
    }
    return Promise.reject(error)
  }
)

(2)提前续期(更丝滑)

如果等Token完全过期再换新,用户可能会遇到卡顿。更优解是在Token快过期时提前续期

// 检查Token剩余时间
function checkTokenExpiry() {
  const token = localStorage.getItem('access_token')
  if (!token) return false
  
  const payload = JSON.parse(atob(token.split('.')[1])) // 解析JWT
  const expiresIn = payload.exp * 1000 - Date.now()
  
  // 如果还剩5分钟过期,就续期
  if (expiresIn < 5 * 60 * 1000) {
    refreshToken()
  }
}

// 定时检查(每10分钟一次)
setInterval(checkTokenExpiry, 10 * 60 * 1000)

三、安全注意事项

Refresh Token 必须HttpOnly + Secure(防止XSS盗取)

短期Token有效期别太长(建议2小时以内)

单点登录(SSO)场景要额外处理

四、实际项目踩坑记录

去年我做的一个后台系统,Token过期问题特别严重,用户经常填表到一半被踢出。

优化前:Token 2小时过期,直接跳登录页,用户投诉爆炸

优化后

  • Access Token 2小时过期
  • Refresh Token 7天过期
  • 提前5分钟自动续期
  • 最终用户几乎感知不到Token刷新,体验大幅提升!

五、知识延展

前端怎么无感刷新token

当 Token 过期时,前端可以使用以下两种无感刷新 Token 的方案:

1. 使用刷新Token(Refresh Token)

在登录成功后,后端会返回两个Token,一个是Access Token,一个是Refresh Token。前端需要将这两个Token保存到本地存储中,例如localStorage或sessionStorage中,以便在需要时使用。

当需要访问API时,前端将从本地存储中获取Access Token,并将其放入请求头中发送到后端。如果Access Token过期了,后端会返回一个错误响应,并提示前端进行刷新Token的操作。

前端可以使用下面的代码实现刷新Token的操作:

function refreshToken() {
  const refreshToken = localStorage.getItem('refreshToken');
  // 发送请求到后端,获取新的Access Token
  fetch('/api/refreshToken', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ refreshToken })
  })
  .then(response => response.json())
  .then(data => {
    // 将新的Access Token更新到本地存储中
    localStorage.setItem('accessToken', data.accessToken);
  })
  .catch(error => {
    console.error('刷新Token失败:', error);
  });
}

当需要刷新Token时,前端可以调用refreshToken函数,该函数会向后端发送请求,获取新的Access Token,并将其更新到本地存储中。在使用API时,前端需要检查Access Token是否过期,如果过期了,则需要调用refreshToken函数来获取新的Access Token。

2. 使用续期接口

在登录成功后,后端会返回一个Access Token和一个过期时间。前端可以将Access Token和过期时间保存到本地存储中,以便在需要时使用。

前端需要定时检查Access Token是否过期,如果过期了,则需要向后端发送续期请求来更新Access Token的过期时间。下面是一个示例代码:

function renewToken() {
  const accessToken = localStorage.getItem('accessToken');
  const expireTime = localStorage.getItem('expireTime');
  // 计算AccessToken的剩余有效时间
  const remainTime = expireTime - Date.now();
  // 如果AccessToken的剩余有效时间小于5分钟,则发送续期请求
  if (remainTime < 5 * 60 * 1000) {
    // 发送续期请求到后端,更新AccessToken的过期时间
    fetch('/api/renewToken', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ accessToken })
    })
    .then(response => response.json())
    .then(data => {
      // 将新的过期时间更新到本地存储中
      localStorage.setItem('expireTime', data.expireTime);
    })
    .catch(error => {
      console.error('续期Token失败:', error);
    });
  }
}

// 定时检查AccessToken的过期时间
setInterval(renewToken, 60 * 1000);

上面的代码中,renewToken函数会检查Access Token的过期时间,如果剩余有效时间小于5分钟,则会向后端发送续期请求来更新AccessToken的过期时间。在使用API时,前端需要定时调用renewToken函数来检查Access Token的过期时间,并更新过期时间。

六、总结

Token过期处理得好,用户体验直接起飞!核心思路:

  • 短期Token + 长期Refresh Token
  • Axios拦截器自动换新Token
  • 提前续期避免卡顿
  • 安全存储Refresh Token

如果你的项目还在用“Token过期就跳登录”的粗暴方案,赶紧优化吧!

​到此这篇关于Vue如何优雅处理Token过期并自动续期的文章就介绍到这了,更多相关Vue处理Token过期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vant中的toast层级改变操作

    vant中的toast层级改变操作

    这篇文章主要介绍了vant中的toast层级改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • vue实现搜索关键词高亮的详细教程

    vue实现搜索关键词高亮的详细教程

    这篇文章主要为大家介绍了vue实现搜索关键词高亮的详细教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • vue 路由视图 router-view嵌套跳转的实现

    vue 路由视图 router-view嵌套跳转的实现

    这篇文章主要介绍了vue 路由视图 router-view嵌套跳转,主要实现的内容有制作一个登录页面,跳转到首页,首页包含菜单栏、顶部导航栏、主体,标准的后台网页格式,菜单点击显示不同的页面,感兴趣的小伙伴请参考下面文章内容
    2021-09-09
  • Vant弹出列表多选输入框下拉选择代码(可直接复制使用)

    Vant弹出列表多选输入框下拉选择代码(可直接复制使用)

    vue项目无论是用element中的Select选择器,还是使用公司维护的组件,都可以轻松实现单选和多选的需求,这篇文章主要给大家介绍了关于Vant弹出列表多选输入框下拉选择的相关资料,需要的朋友可以参考下
    2024-01-01
  • vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法)

    vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法)

    这篇文章主要介绍了vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 浅谈mvvm-simple双向绑定简单实现

    浅谈mvvm-simple双向绑定简单实现

    本篇文章主要介绍了浅谈mvvm-simple双向绑定简单实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • 路由vue-route的使用示例教程

    路由vue-route的使用示例教程

    这篇文章主要介绍了路由vue-route的使用,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • vue3中关于i18n字符串转义问题

    vue3中关于i18n字符串转义问题

    这篇文章主要介绍了vue3中关于i18n字符串转义问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • VSCode搭建vue项目的实现步骤

    VSCode搭建vue项目的实现步骤

    本文主要介绍了VSCode搭建vue项目的实现步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • vue打包后dist文件在本地启动运行的步骤

    vue打包后dist文件在本地启动运行的步骤

    这篇文章主要给大家介绍了关于vue打包后dist文件在本地启动运行的简单步骤,文中通过代码示例以及图文介绍的非常详细,对大家学习或者使用vue具有一定的参考价值,需要的朋友可以参考下
    2023-09-09

最新评论