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

四、架构图解:

相关推荐
Warren9813 分钟前
软件测试-Selenium学习笔记
java·javascript·笔记·学习·selenium·测试工具·安全
字节跳动安全中心23 分钟前
智能体防御 | 一文了解3种系统提示词加固方法
安全·llm
黑客影儿4 小时前
黑客哲学之学习笔记系列(三)
笔记·学习·程序人生·安全·职场和发展·网络攻击模型·学习方法
XY_墨莲伊4 小时前
【网络安全实验报告】实验六: 病毒防护实验
安全·web安全
厦门辰迈智慧科技有限公司5 小时前
水闸安全综合监测系统解决方案
网络·物联网·安全·自动化·监测
深盾安全5 小时前
Python脚本安全防护策略全解析(下)
安全
叫我阿柒啊6 小时前
自学渗透,学会五分钟安装DVWA漏洞靶场
后端·安全
小云数据库服务专线14 小时前
GaussDB 数据库架构师修炼(十三)安全管理(5)-动态数据脱敏
安全·数据库架构·gaussdb
lingggggaaaa15 小时前
小迪安全v2023学习笔记(六十二讲)—— PHP框架反序列化
笔记·学习·安全·web安全·网络安全·php·反序列化
黑客影儿18 小时前
Kali Linux 环境中的系统配置文件与用户配置文件大全
linux·运维·程序人生·安全·网络安全·系统安全·学习方法