侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

如何安全地在浏览器端存储和传输JWT令牌?

2025-12-12 / 0 评论 / 4 阅读

题目

如何安全地在浏览器端存储和传输JWT令牌?

信息

  • 类型:问答
  • 难度:⭐⭐

考点

JWT安全存储,传输安全措施,CSRF/XSS防御

快速回答

安全处理JWT的核心要点:

  • 存储选择:优先使用HttpOnly的Cookie存储,避免localStorage/sessionStorage
  • 传输安全:始终通过HTTPS传输,设置Secure和SameSite属性
  • 令牌设计:使用短期有效的access token配合refresh token机制
  • 防御措施:添加CSRF Token防御跨站请求伪造
  • 敏感操作:关键操作要求重新认证
## 解析

一、原理说明

JWT(JSON Web Token)是无状态认证的核心机制,包含Header、Payload、Signature三部分。浏览器端安全风险主要来自:

  • XSS攻击:恶意脚本窃取存储的令牌
  • CSRF攻击:诱导用户发送非法请求
  • 中间人攻击:未加密通道传输令牌

二、最佳实践与代码示例

1. 安全存储方案

// 后端设置HttpOnly Cookie(Node.js示例)
res.cookie('token', accessToken, {
  httpOnly: true,    // 阻止JavaScript访问
  secure: true,      // 仅通过HTTPS传输
  sameSite: 'Strict',// 阻止跨站发送
  maxAge: 15 * 60 * 1000 // 15分钟有效期
});

替代方案:若必须使用localStorage:

// 前端加密存储(AES示例)
const encryptedToken = CryptoJS.AES.encrypt(
  token, 
  '动态获取的秘钥'
).toString();
localStorage.setItem('encToken', encryptedToken);

2. 安全传输机制

  • 所有API请求自动携带Cookie(浏览器默认行为)
  • 敏感请求附加CSRF Token:
    <!-- 前端嵌入CSRF Token -->
    <meta name="csrf-token" content="{{csrfToken}}"> 
    
    <!-- Axios拦截器示例 -->
    axios.defaults.headers.common['X-CSRF-Token'] = getCSRFToken();

3. 令牌生命周期管理

// 双令牌机制示例
{
  "access_token": "eyJ...",  // 短期令牌(15分钟)
  "refresh_token": "eyJ..." // 长期令牌(7天,存储于HttpOnly Cookie)
}

三、常见错误

  • 致命错误:localStorage存储+无HTTPS传输
  • 配置缺陷:未设置SameSite属性导致CSRF风险
  • 过度信任:使用JWT payload存储敏感数据(未加密)
  • 长效令牌:access token有效期超过30分钟

四、扩展知识

  • 令牌吊销:通过黑名单或refresh token轮转实现
  • 增强措施
    • 指纹绑定:将用户设备指纹加入JWT签名
    • 令牌分割:access token拆分为两个部分存储
  • 新标准:Backend-for-Frontend模式替代直接存储

五、防御方案对比

方案 防XSS 防CSRF 实施复杂度
HttpOnly Cookie 需配合SameSite
localStorage + CSRF Token
内存存储(单页应用) 需额外处理