JWT(JSON Web Token)详解
JWT 是一种基于 JSON 的轻量级身份认证和授权规范,广泛应用于分布式系统、前后端分离架构中,用于在客户端和服务端之间安全传递信息。下面将从 JWT 的核心概念、工作流程、技术细节及应用场景等方面进行详细介绍。
JWT 的核心价值:为何需要它?
在传统的 Web 开发中,常用Session+Cookie实现身份认证,但这种方式存在明显局限性:
- 服务端存储压力:Session 需要服务端保存用户状态,用户量增大时会占用大量服务器资源。
- 集群部署难题:Session 存储在单个服务器上,集群环境下需额外配置(如 Session 共享、Redis 同步)才能保证用户跨节点访问时的身份一致性。
- 违背无状态原则:Restful API 强调服务端无状态,Session 机制与这一理念冲突。
JWT 的出现正是为了解决这些问题,其核心优势在于:
- 无状态:服务端无需保存用户状态,所有信息都封装在 Token 中。
- 跨域 / 跨服务支持:Token 可在不同域名、不同服务间传递,适合分布式系统。
- 自包含:Token 本身包含用户身份信息,减少服务端查询数据库的次数。
JWT 的工作流程
JWT 的身份认证流程可分为以下步骤:
- 用户登录:客户端向服务端发送用户名、密码等认证信息。
- 生成 Token:服务端验证通过后,根据用户信息生成 JWT Token 并返回给客户端。
- 客户端存储 Token:客户端(如浏览器、APP)将 Token 保存在 LocalStorage、Cookie 或内存中。
- 后续请求携带 Token:客户端每次请求时,通过 HTTP 头部(如
Authorization: Bearer <token>)携带 Token。 - 服务端验证 Token:服务端接收 Token 后,验证其有效性(签名、过期时间等),验证通过则解析用户信息并处理请求。
JWT 的结构组成
JWT 由三部分组成,用英文句号(.)分隔,格式为:header.payload.signature。
1. 头部(Header)
头部用于描述 JWT 的类型和签名算法,是一个 JSON 对象,包含以下字段:
alg:签名算法(如 HS256、RS256 等)。typ:Token 类型,固定为JWT。
示例:
1 | { |
头部会经过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 唯一标识(用于防止重放攻击)。
- 自定义字段:根据业务需求添加的用户信息(如
userId、role等)。
示例:
1 | { |
载荷也会经过Base64URL 编码,形成 JWT 的第二部分。
注意:Base64 编码是可逆的,因此不要在载荷中存放敏感信息(如密码)。
3. 签名(Signature)
签名是 JWT 的安全保障,用于验证 Token 是否被篡改,以及确认签发者的合法性。生成规则如下:
- 拼接编码后的头部和载荷:
base64UrlEncode(header) + "." + base64UrlEncode(payload)。 - 使用头部指定的算法(如 HS256),结合服务端秘钥(Secret) 对拼接后的字符串进行加密,得到签名。
公式示例(HS256 算法):
1 | signature = HMACSHA256( |
最终,JWT 的完整格式为:编码后的header.编码后的payload.签名,例如:
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
JWT 的验证原理
服务端接收 JWT 后,验证流程如下:
- 拆分 Token 为 header、payload、signature 三部分。
- 对 header 和 payload 进行 Base64URL 解码,获取算法和用户信息。
- 使用相同的算法和服务端秘钥,重新计算签名(基于解码后的 header 和 payload)。
- 对比重新计算的签名与 Token 中的 signature:
- 一致:Token 未被篡改,且验证过期时间(
exp)、生效时间(nbf)等字段是否有效。 - 不一致:Token 被篡改,拒绝请求。
- 一致:Token 未被篡改,且验证过期时间(
JWT 的优缺点
优点
- 无状态:服务端无需存储用户状态,减轻服务器压力,适合集群部署。
- 自包含:减少服务端查询数据库的次数,提高效率。
- 跨平台:支持多语言、多终端(Web、APP、小程序等)。
- 安全性:签名机制确保数据不被篡改(前提是秘钥安全)。
缺点
- 无法即时吊销:Token 一旦生成,在过期前始终有效(除非服务端维护黑名单,但会破坏无状态特性)。
- 载荷不宜过大:Token 会随每次请求传递,过大可能增加网络开销。
- 秘钥管理风险:对称加密(如 HS256)中,秘钥泄露会导致 Token 被伪造;非对称加密(如 RS256)需管理公钥和私钥。
JWT 的应用场景
- 身份认证:前后端分离架构中,替代 Session 实现用户登录状态保持。
- API 授权:第三方应用访问服务端 API 时,通过 JWT 验证权限。
- 信息传递:在分布式系统中安全传递用户信息(如微服务间调用)。
使用 JWT 的注意事项
- 秘钥安全:秘钥是 JWT 安全的核心,必须妥善保管,避免泄露。
- 合理设置过期时间:根据业务需求设置
exp字段(如 1 小时),减少 Token 被盗用的风险。 - 避免敏感信息:载荷中禁止存放密码、银行卡号等敏感数据。
- 选择合适的加密算法:HS256(对称加密,适合单服务)、RS256(非对称加密,适合多服务)。
- HTTPS 传输:防止 Token 在网络传输中被窃取
v1.3.10