面试官: “ 请问你怎么理解 JWT ? ”

40 阅读3分钟

1. 什么是 JWT

JWT 是一种轻量级的身份验证和信息交换标准,它通过 JSON 格式在客户端和服务器之间安全地传输信息。

特点:

  • 无状态:服务器不需要保存会话数据,所有信息都在 Token 中
  • 自包含:Token 中包含用户身份、权限等信息,减少数据库查询
  • 跨域支持:可以在不同域之间传递
  • 可扩展:可以根据需要添加自定义字段

2. JWT 的结构

一个 JWT 由三部分组成,用 . 分隔:

Header.Payload.Signature

(1)Header(头部)

  • 描述 Token 的类型(JWT)和签名算法(如 HS256RS256

  • 示例:

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  • 经过 Base64Url 编码后成为第一部分

(2)Payload(载荷)

  • 存放实际需要传输的数据(如用户 ID、用户名、权限等)

  • 包含标准字段(可选):

    • iss:签发者
    • exp:过期时间
    • sub:主题
    • aud:受众
  • 也可以添加自定义字段

  • 示例:

    {
      "sub": "1234567890",
      "name": "Tom",
      "role": "admin",
      "exp": 1735689600
    }
    
  • 经过 Base64Url 编码后成为第二部分

(3)Signature(签名)

  • 用于验证 Token 是否被篡改

  • 签名算法:

    • HS256:使用密钥进行对称加密
    • RS256:使用公钥 / 私钥进行非对称加密
  • 签名公式:

    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secretKey
    )
    
  • 签名结果经过 Base64Url 编码后成为第三部分


3. JWT 的工作流程

  1. 用户登录

    • 用户输入用户名和密码,发送到服务器
    • 服务器验证成功后,生成 JWT
  2. 服务器返回 JWT

    • 服务器将 JWT 作为响应返回给客户端

    • 客户端将 JWT 存储在:

      • localStorage
      • sessionStorage
      • cookie
  3. 客户端发送请求时携带 JWT

    • 客户端在每次请求的 Authorization 头中添加:

      Authorization: Bearer <token>
      
  4. 服务器验证 JWT

    • 服务器收到请求后,验证 JWT 的签名和过期时间
    • 验证通过后,根据 Token 中的用户信息授权访问资源

4. JWT 的优缺点

优点

  • 无状态:服务器不需要保存会话数据,便于扩展
  • 跨域支持:可以在不同域之间传递
  • 自包含:减少数据库查询
  • 灵活性高:可以根据需要添加自定义字段

缺点

  • 无法撤销:一旦签发,在过期前始终有效(除非服务器维护黑名单)
  • Payload 可解码:虽然不能篡改,但不要存放敏感信息(如密码)
  • Token 较长:可能增加网络传输开销

5. JWT 的安全注意事项

  • 使用 HTTPS:防止 Token 在传输过程中被窃取
  • 设置合理的过期时间:短期 Token 减少被盗用风险
  • 不要存储敏感信息:Payload 可以被解码
  • 使用非对称加密算法(如 RS256):提高安全性
  • 配合 Refresh Token:实现无感刷新

6. 示例:使用 JWT(Node.js + jsonwebtoken)

(1)生成 JWT

const jwt = require('jsonwebtoken');

// 生成 Token
const token = jwt.sign(
  { sub: '123', name: 'Tom', role: 'admin' }, // Payload
  'your-secret-key',                          // 密钥
  { expiresIn: '1h' }                         // 过期时间
);

console.log(token);

(2)验证 JWT

const jwt = require('jsonwebtoken');

app.get('/protected', (req, res) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ msg: '未提供 Token' });
  }

  const token = authHeader.split(' ')[1];

  try {
    const decoded = jwt.verify(token, 'your-secret-key');
    res.json({ user: decoded, data: '敏感数据' });
  } catch (err) {
    res.status(403).json({ msg: 'Token 无效或已过期' });
  }
});

✅ 总结

  • JWT 是一种轻量级的身份验证标准,由 Header、Payload、Signature 三部分组成
  • 工作流程:登录 → 生成 Token → 客户端存储 → 请求时携带 → 服务器验证
  • 优点:无状态、跨域支持、自包含
  • 缺点:无法撤销、Payload 可解码
  • 安全使用:HTTPS、合理过期时间、非对称加密