🔐 JWT 认证机制详解

JSON Web Token - 现代Web认证的标准方案

📚 什么是JWT?

JWT (JSON Web Token) 是一个开放标准 (RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。

JWT 结构组成

Header
头部 - 令牌类型 + 签名算法
.
Payload
载荷 - 实际传输的数据
.
Signature
签名 - 验证令牌完整性
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

详细说明

// 1. Header (头部) - 描述令牌的元数据 { "alg": "HS256", // 签名算法 "typ": "JWT" // 令牌类型 } // 2. Payload (载荷) - 包含实际要传输的数据 (Claims) { "sub": "1234567890", // 主题 (用户ID) "name": "John Doe", // 用户名 "iat": 1516239022 // 签发时间 } // 3. Signature (签名) - 确保令牌未被篡改 // HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

🔄 认证流程对比

🍪 传统Session认证

  • 1 用户输入账号密码登录
  • 2 服务器验证 credentials
  • 3 服务器创建Session,存储用户数据
  • 4 Session ID 通过 Cookie 返回给客户端
  • 5 后续请求携带 Cookie (Session ID)
  • 6 服务器根据 Session ID 查询存储的用户信息

🎫 JWT认证

  • 1 用户输入账号密码登录
  • 2 服务器验证 credentials
  • 3 服务器生成JWT (包含用户信息,签名)
  • 4 JWT 返回给客户端 (通常放在响应体或Header)
  • 5 后续请求在 Authorization Header 中携带JWT
  • 6 服务器验证JWT签名,解析用户信息 (无状态)

⚖️ 详细对比分析

对比维度 传统Session认证 JWT认证
状态管理 服务端存储Session (有状态) 服务端不存储 (无状态)
存储位置 Session ID在Cookie,数据在服务器内存/数据库 完整Token在客户端 (LocalStorage/Cookie)
扩展性 差 - 需要Session共享 (Redis等) 好 - 天然支持分布式
跨域支持 困难 - Cookie跨域限制 容易 - 可放在Authorization Header
移动端支持 不方便 - Cookie管理复杂 友好 - 纯Token机制
性能 每次请求需要查询Session存储 只需验证签名,无需数据库查询
Token大小 小 - 只有Session ID 大 - 包含完整Payload
注销/过期 容易 - 删除服务端Session即可 困难 - 需要黑名单或短过期时间
安全性 依赖Cookie安全 (HttpOnly, Secure等) 需要防范XSS (LocalStorage存储时)

✅ JWT 的优势与劣势

✅ 优势

  • 无状态:服务器不需要存储会话信息,易于扩展
  • 跨域友好:不依赖Cookie,适合API认证
  • 移动端友好:iOS、Android等原生应用易于集成
  • 性能好:避免频繁的数据库查询
  • 支持签名和加密:保证数据完整性和机密性
  • 标准化:RFC标准,有成熟的库支持

⚠️ 劣势与注意事项

  • Token体积大:每次请求都携带完整Token,增加带宽消耗
  • 无法主动撤销:Token一旦签发,在过期前一直有效 (除非维护黑名单)
  • 存储安全风险:放在LocalStorage有XSS风险,放在Cookie需防范CSRF
  • 敏感信息泄露:Payload是Base64编码,可被解码 (不能存储敏感信息)
  • 过期时间难以控制:需要配合Refresh Token机制

🛠️ 实际使用演示

JWT生成与验证模拟

点击上方按钮查看演示...

代码示例

// Node.js + jsonwebtoken 库示例 const jwt = require('jsonwebtoken'); // 1. 生成JWT const token = jwt.sign({ userId: '123456', username: '张三', role: 'admin' }, 'your-secret-key', { expiresIn: '1h' // 1小时过期 }); // 2. 验证JWT try { const decoded = jwt.verify(token, 'your-secret-key'); console.log(decoded); // { userId: '123456', username: '张三', ... } } catch (err) { console.log('Token无效或已过期'); } // 3. 客户端存储和使用 // 存储 localStorage.setItem('token', token); // 请求时携带 fetch('/api/protected', { headers: { 'Authorization': 'Bearer ' + localStorage.getItem('token') } });

💡 JWT 最佳实践

安全建议

  • ✅ 使用HTTPS传输Token,防止中间人攻击
  • ✅ 设置合理的过期时间 (配合Refresh Token)
  • ✅ 使用HttpOnly + Secure Cookie存储Token (防XSS)
  • ✅ 对敏感操作要求重新认证
  • ✅ 实现Token黑名单机制 (用于注销)
  • ✅ 使用强密钥,定期更换
  • ❌ 不要在Payload中存储敏感信息 (密码等)
  • ❌ 不要将Token存储在localStorage (有XSS风险)

Refresh Token 机制

  • 1 用户登录,服务器返回 Access Token (短过期,如15分钟) 和 Refresh Token (长过期,如7天)
  • 2 客户端使用Access Token访问API
  • 3 Access Token过期,客户端使用Refresh Token请求新的Access Token
  • 4 服务器验证Refresh Token,签发新的Access Token
  • 5 Refresh Token过期,用户需要重新登录