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

四、架构图解:

相关推荐
霖霖总总19 小时前
[小技巧19]MySQL 权限管理全指南:用户、角色、授权与安全实践
数据库·mysql·安全
tianyuanwo1 天前
合并XFS分区:将独立分区安全融入LVM的完整指南
安全·lvm
智驱力人工智能1 天前
守护流动的规则 基于视觉分析的穿越导流线区检测技术工程实践 交通路口导流区穿越实时预警技术 智慧交通部署指南
人工智能·opencv·安全·目标检测·计算机视觉·cnn·边缘计算
2501_945837431 天前
云服务器的防护体系构建之道
网络·安全
小红卒1 天前
海康威视未授权访问漏洞 (CVE-2017-7921)复现研究
安全
Data-Miner1 天前
精品可编辑PPT | 大模型与智能体安全风险治理与防护
安全
咕噜企业分发小米1 天前
直播云服务器安全防护有哪些最新的技术趋势?
运维·服务器·安全
九河云2 天前
数据驱动未来,华为云DWS为智能决策提速
大数据·人工智能·安全·机器学习·华为云
Dr.Alex Wang2 天前
Google Firebase 实战教学 - Streamlit、Bucket、Firebase
数据库·python·安全·googlecloud
chipsense2 天前
强电流环境下用霍尔电流传感器,安全性能有保障么?
安全·霍尔电流传感器