0%

JWT介绍

JWT(JSON Web Token)详解

JWT 是一种基于 JSON 的轻量级身份认证和授权规范,广泛应用于分布式系统、前后端分离架构中,用于在客户端和服务端之间安全传递信息。下面将从 JWT 的核心概念、工作流程、技术细节及应用场景等方面进行详细介绍。

JWT 的核心价值:为何需要它?

在传统的 Web 开发中,常用Session+Cookie实现身份认证,但这种方式存在明显局限性:

  • 服务端存储压力:Session 需要服务端保存用户状态,用户量增大时会占用大量服务器资源。
  • 集群部署难题:Session 存储在单个服务器上,集群环境下需额外配置(如 Session 共享、Redis 同步)才能保证用户跨节点访问时的身份一致性。
  • 违背无状态原则:Restful API 强调服务端无状态,Session 机制与这一理念冲突。

JWT 的出现正是为了解决这些问题,其核心优势在于:

  • 无状态:服务端无需保存用户状态,所有信息都封装在 Token 中。
  • 跨域 / 跨服务支持:Token 可在不同域名、不同服务间传递,适合分布式系统。
  • 自包含:Token 本身包含用户身份信息,减少服务端查询数据库的次数。

JWT 的工作流程

JWT 的身份认证流程可分为以下步骤:

  1. 用户登录:客户端向服务端发送用户名、密码等认证信息。
  2. 生成 Token:服务端验证通过后,根据用户信息生成 JWT Token 并返回给客户端。
  3. 客户端存储 Token:客户端(如浏览器、APP)将 Token 保存在 LocalStorage、Cookie 或内存中。
  4. 后续请求携带 Token:客户端每次请求时,通过 HTTP 头部(如Authorization: Bearer <token>)携带 Token。
  5. 服务端验证 Token:服务端接收 Token 后,验证其有效性(签名、过期时间等),验证通过则解析用户信息并处理请求。

JWT 的结构组成

JWT 由三部分组成,用英文句号(.)分隔,格式为:header.payload.signature

1. 头部(Header)

头部用于描述 JWT 的类型和签名算法,是一个 JSON 对象,包含以下字段:

  • alg:签名算法(如 HS256、RS256 等)。
  • typ:Token 类型,固定为JWT

示例:

1
2
3
4
{
"alg": "HS256", // 使用HMAC-SHA256算法签名
"typ": "JWT" // 类型为JWT
}

头部会经过Base64URL 编码(与标准 Base64 的区别是替换了+-/_,去除了末尾=),形成 JWT 的第一部分。

2. 载荷(Payload)

载荷是 JWT 的核心,用于存储需要传递的用户信息或其他数据,同样是一个 JSON 对象。字段分为三类:

  • 标准注册字段(建议但非强制使用):
    • iss:Token 的签发者。
    • sub:Token 所面向的用户(subject)。
    • aud:Token 的接收者(audience)。
    • exp:过期时间(timestamp,必须大于签发时间)。
    • nbf:生效时间(timestamp,在此时间前 Token 无效)。
    • iat:签发时间(issued at)。
    • jti:Token 唯一标识(用于防止重放攻击)。
  • 自定义字段:根据业务需求添加的用户信息(如userIdrole等)。

示例:

1
2
3
4
5
6
7
{
"sub": "1234567890", // 用户ID
"name": "John Doe", // 用户名
"role": "admin", // 自定义角色字段
"iat": 1516239022, // 签发时间
"exp": 1516242622 // 过期时间(1小时后)
}

载荷也会经过Base64URL 编码,形成 JWT 的第二部分。
注意:Base64 编码是可逆的,因此不要在载荷中存放敏感信息(如密码)。

3. 签名(Signature)

签名是 JWT 的安全保障,用于验证 Token 是否被篡改,以及确认签发者的合法性。生成规则如下:

  1. 拼接编码后的头部和载荷:base64UrlEncode(header) + "." + base64UrlEncode(payload)
  2. 使用头部指定的算法(如 HS256),结合服务端秘钥(Secret) 对拼接后的字符串进行加密,得到签名。

公式示例(HS256 算法):

1
2
3
4
5
signature = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret // 服务端秘钥,必须保密
)

最终,JWT 的完整格式为:编码后的header.编码后的payload.签名,例如:

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT 的验证原理

服务端接收 JWT 后,验证流程如下:

  1. 拆分 Token 为 header、payload、signature 三部分。
  2. 对 header 和 payload 进行 Base64URL 解码,获取算法和用户信息。
  3. 使用相同的算法和服务端秘钥,重新计算签名(基于解码后的 header 和 payload)。
  4. 对比重新计算的签名与 Token 中的 signature:
    • 一致:Token 未被篡改,且验证过期时间(exp)、生效时间(nbf)等字段是否有效。
    • 不一致:Token 被篡改,拒绝请求。

JWT 的优缺点

优点

  • 无状态:服务端无需存储用户状态,减轻服务器压力,适合集群部署。
  • 自包含:减少服务端查询数据库的次数,提高效率。
  • 跨平台:支持多语言、多终端(Web、APP、小程序等)。
  • 安全性:签名机制确保数据不被篡改(前提是秘钥安全)。

缺点

  • 无法即时吊销:Token 一旦生成,在过期前始终有效(除非服务端维护黑名单,但会破坏无状态特性)。
  • 载荷不宜过大:Token 会随每次请求传递,过大可能增加网络开销。
  • 秘钥管理风险:对称加密(如 HS256)中,秘钥泄露会导致 Token 被伪造;非对称加密(如 RS256)需管理公钥和私钥。

JWT 的应用场景

  • 身份认证:前后端分离架构中,替代 Session 实现用户登录状态保持。
  • API 授权:第三方应用访问服务端 API 时,通过 JWT 验证权限。
  • 信息传递:在分布式系统中安全传递用户信息(如微服务间调用)。

使用 JWT 的注意事项

  1. 秘钥安全:秘钥是 JWT 安全的核心,必须妥善保管,避免泄露。
  2. 合理设置过期时间:根据业务需求设置exp字段(如 1 小时),减少 Token 被盗用的风险。
  3. 避免敏感信息:载荷中禁止存放密码、银行卡号等敏感数据。
  4. 选择合适的加密算法:HS256(对称加密,适合单服务)、RS256(非对称加密,适合多服务)。
  5. HTTPS 传输:防止 Token 在网络传输中被窃取

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10