JWT验证

54 阅读4分钟

一、JWT(JSON Web Token)核心概念(高频考点)

1. 本质

JWT是一种基于JSON的、用于在网络上安全传递信息的开放标准(RFC 7519),通常由三部分组成:

  • Header(头部):包含令牌类型(如JWT)和签名算法(如HS256);
  • Payload(载荷):包含声明(Claims,如用户ID、角色、过期时间);
  • Signature(签名):对前两部分的签名,确保数据不被篡改。

2. 格式

JWT以点分隔的字符串形式存在,例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOjEsInJvbGUiOiJhZG1pbiIsImV4cCI6MTY5MDY1MjQwMH0.
T5cG0J7oXn7n3p8z7n5e2q5l3v6d8m5c9t3a5d7j8

(实际应用中通常更长,且不可读)

二、JWT验证的工作流程(高频考点)

1. 生成JWT(登录时)

  1. 用户登录成功,服务器根据用户信息(如ID、角色)生成Payload;
  2. 结合Header(指定算法)和服务器私钥,生成Signature;
  3. 返回完整JWT给客户端(通常在响应头或JSON中)。

2. 验证JWT(请求时)

  1. 客户端每次请求时,在请求头(如Authorization: Bearer <token>)中携带JWT;
  2. 服务器接收JWT,分离三部分:
    • 用相同算法和私钥重新计算Signature;
    • 对比计算出的Signature与接收到的Signature是否一致(防篡改);
    • 验证Payload中的声明(如exp过期时间、iss发行人)是否合法。
  3. 验证通过则认为请求有效,返回资源;否则返回401(未授权)。

三、安全机制(高频考点)

1. 防篡改

  • Signature由Header、Payload和私钥生成,若数据被篡改,签名验证将失败。

2. 防伪造

  • 私钥仅服务器持有,攻击者无法生成合法签名,除非私钥泄露。

3. 过期控制

  • Payload中可设置exp(过期时间),服务器验证时自动拒绝过期令牌。

4. HTTPS保护

  • 传输过程需通过HTTPS加密,防止中间人截获令牌。

四、应用场景(结合项目经验)

1. 身份验证

  • 替代传统Session-Cookie方案,支持跨域(如前后端分离项目)。

2. 信息交换

  • 安全传递用户信息(如用户ID、权限),避免多次查询数据库。

3. 单点登录(SSO)

  • 多个子系统间共享身份信息,只需登录一次。

4. 无状态API

  • 服务器无需存储会话信息,天然支持微服务和分布式架构。

五、优缺点(面试必答)

1. 优点

  • 无状态:不依赖服务器存储会话,适合微服务和云原生环境;
  • 跨域支持:可通过localStorage/cookie存储,跨域传递;
  • 自包含:Payload包含用户信息,减少数据库查询;
  • 扩展性:可自定义Claims,灵活添加业务信息。

2. 缺点

  • 体积大:Base64编码后体积较大,频繁携带会增加请求数据量;
  • 安全性依赖HTTPS:明文传输易被截获,必须配合HTTPS;
  • 无法主动失效:一旦颁发,直到过期前都有效(可通过黑名单机制缓解);
  • Payload易被解码:敏感信息需加密处理(如用户密码)。

六、代码示例(直观理解)

1. 生成JWT(Node.js服务器端)

const jwt = require('jsonwebtoken');

// 登录成功后生成JWT
const secretKey = 'your-secret-key'; // 服务器私钥
const payload = {
  userId: 123,
  role: 'admin',
  exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1小时后过期
};

const token = jwt.sign(payload, secretKey);
console.log(token); // 生成的JWT

2. 验证JWT(服务器中间件)

function verifyToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // 格式:Bearer <token>

  if (!token) return res.sendStatus(401);

  jwt.verify(token, secretKey, (err, user) => {
    if (err) return res.sendStatus(403); // 无效令牌
    req.user = user; // 将用户信息挂载到请求对象
    next(); // 继续处理请求
  });
}

七、总结

“JWT验证是一种基于Token的无状态认证机制,核心是通过数字签名确保信息在传输过程中不被篡改和伪造。其工作流程包括‘登录生成Token→请求携带Token→服务器验证Token’三个关键步骤,适合跨域、分布式系统和微服务架构。优点是无状态、跨域支持和自包含,缺点是体积大、无法主动失效。实际项目中,配合HTTPS使用,将Token存储在HttpOnly Cookie中,并通过黑名单机制处理登出场景,以提升安全性。”