前端Token管理终极指南:安全存储 + 无感刷新

一、引言:为什么Token管理是前端核心能力

  • 现代 Web 应用的认证架构演进 :Session -> JWT -> OAuth2.0
  • 前端 Token 管理的三大挑战: 安全性、无感刷新、状态同步

二、双 Token 机制 :安全架构

1、令牌分工原理

json 复制代码
// 令牌结构示例
{
  "access_token": "eyJhbG...",  // 短期令牌(30分钟)
  "refresh_token": "f7a2e...", // 长期令牌(7天)
  "expires_in": 1800          // 过期时间
}
  • access_token:高频使用,携带用户身份,必须短时效
  • refresh_token:仅用于刷新,绝不出现在常规请求中

2.安全存储方案对比

存储位置 适用令牌类型 安全等级 生命周期 风险
sessionStorage access_token ★★★★☆ 标签页关闭时失效 XSS 可读取
内存变量 refresh_token ★★★★★ 页面刷新即丢失 无法持久化
HttpOnly Cookie refresh_token ★★★★★ 可设长时效 需防 CSRF
localStorage 不推荐 ★☆☆☆☆ 永久存储 XSS 完全暴露

💡 黄金法则:Access Token 存易失位置,Refresh Token 用 HttpOnly Cookie

3、无感刷新实战:Axios 拦截器深度优化

javascript 复制代码
// 请求拦截器
service.interceptors.request.use(
  (config) => {
    try {
      // 从sessionStorage获取access_token
      const token = sessionStorage.getItem('access_token')
      if (token) {
        config.headers.Authorization = `${token}`
      }
      return config
    } catch (error) {
      console.error('获取token失败:', error)
      return config
    }
  },
  (error) => {
    return Promise.reject(error)
  },
)
javascript 复制代码
// 响应拦截器
service.interceptors.response.use(
  (response) => {
    return response
  },
  async (error) => {
    // 获取错误响应状态
    const { response } = error

    if (response?.status === 401) {
      // token过期
      const config = error.config
      if (!isRefreshing) {
        isRefreshing = true
        try {
          // 尝试刷新token
          const userStore = useUserStore()
          const refreshResult = await userStore.refreshToken()
          if (refreshResult) {
            // 重新设置token
            const newToken = sessionStorage.getItem('access_token')
            config.headers.Authorization = newToken
            // 重新请求队列中的请求
            requests.forEach((cb) => cb(newToken))
            requests = []
            // 重试当前请求
            return service(config)
          }
        } catch (err) {
          console.error('刷新token失败:', err)
          // 刷新失败,清空token并跳转到登录页
          const userStore = useUserStore()
          userStore.clearUserInfo()
          window.location.href = '/login'
          return Promise.reject(err)
        } finally {
          isRefreshing = false
        }
      } else {
        // 正在刷新token,将请求加入队列
        return new Promise((resolve) => {
          requests.push((token) => {
            config.headers.Authorization = `${token}`
            resolve(service(config))
          })
        })
      }
    }
    return Promise.reject(error)
  },

三、用户信息pinia持久化

做用户功能时,刷新一下页面用户信息就没了,我是用pinia持久化的,然后发现是没有下载插件和配置pinia-plugin-persistedstate。

javascript 复制代码
{
    persist: {
      // 存储在 sessionStorage 中的键名
      key: 'user-store',
      
      // 使用 sessionStorage 作为存储方式
      storage: window.sessionStorage,
      
      // 只持久化 store 中的 userInfo 数据
      paths: ['userInfo']
    }
}

这个配置的作用是:

1.持久化存储:

  • 当页面刷新时,Pinia store 中的数据会被重置
  • 通过这个配置,指定的数据会自动保存到 sessionStorage 中
  • 页面刷新后,数据会自动从 sessionStorage 恢复到 store 中

2.选择性持久化:

  • paths: 'userInfo' 表示只持久化 store 中的 userInfo 数据
  • 其他数据如 tokenInfo 不会被持久化
  • 这样可以更精确地控制哪些数据需要保存

3.使用 sessionStorage:

  • 数据存储在 sessionStorage 中,而不是 localStorage
  • 这意味着数据只在当前会话期间有效
  • 关闭浏览器后数据会被清除,保证了安全性

举个例子:

arduino 复制代码
// 用户登录后,userInfo 会被自动保存到 sessionStorage
userInfo.value = {
  username: 'test',
  email: 'test@example.com'
}

// 页面刷新后,userInfo 会自动从 sessionStorage 恢复
// 不需要手动处理恢复逻辑

主要好处:

  1. 避免页面刷新后用户信息丢失
  2. 不需要手动管理数据的存储和恢复
  3. 通过 sessionStorage 确保了数据的安全性

四、架构图解:

相关推荐
hz567897 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
浮链序8 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
袁哥大话安全9 小时前
巡隐WEBSHELL扫描软件
人工智能·安全·web
小宋10219 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
草根大哥9 小时前
04-推拉流安全:签名、Token 与防盗链
安全·成本·延迟·自建cdn·ppcdn
云老大-阿里云国际站代理商11 小时前
腾讯云国际站服务代理商:EdgeOne怎么做网站安全?WAF、DDoS和Bot防护分别解决什么问题
安全·腾讯云·ddos
万联WANFLOW11 小时前
从 ARTEX 事件看 AI Agent 安全:工具调用链为何成为新的风险入口?
人工智能·安全·测试
草根大哥11 小时前
02-自建 CDN 架构总览:控制面与媒体面分离
安全·成本·延迟·自建cdn·ppcdn
2603_9695792812 小时前
电脑备份怎么备份?从系统镜像到跨设备同步的几种思路
安全
飞飞传输14 小时前
业务系统文件安全检测怎么做?生物医药企业选型与建设指南
大数据·运维·安全