前端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 确保了数据的安全性

四、架构图解:

相关推荐
探索者0117 小时前
Upoad靶场--文件上传
安全·文件上传·upload靶场
探索者0117 小时前
文件上传漏洞指南:原理+绕过手法与靶场实战
安全·web安全·文件上传
生成论实验室17 小时前
《事件关系阴阳博弈动力学:识势应势之道》第五篇:安全关键关系——故障、障碍与冲突
运维·服务器·人工智能·安全·架构
qcx2317 小时前
拆解 Warp AI Agent(二):风险分级执行——Agent 如何做到安全并行、危险排队
人工智能·安全·ai·agent·源码解析·warp
qcx2317 小时前
拆解 Warp AI Agent(一):类型即协议——23 种 Action 的编译期安全设计
人工智能·安全·ai·agent·源码解析·warp
数字供应链安全产品选型1 天前
关键领域清单+SBOM:834号令下软件供应链的“精准治理“逻辑与技术落地路径
人工智能·安全
byoass1 天前
企业云盘与设计软件深度集成:AutoCAD/Revit/SolidWorks插件开发与API集成实战
服务器·网络·数据库·安全·oracle·云计算
Fullde福德负载箱厂家1 天前
负载箱的需求分析与规格编制:用户应知的采购前期技术准备
安全·制造
ReaF_star1 天前
【安全】SSL证书更新操作手册(Nginx+Cloudflare+acme.sh)
nginx·安全·ssl
盟接之桥1 天前
什么是EDI(电子数据交换)|制造业场景解决方案
大数据·网络·安全·汽车·制造