JWT 是由三部分组成的字符串,每一部分通过 .
进行分隔:
- Header(头部)
- Payload(有效负载)
- Signature(签名)
下面我们来详细了解每个部分及其作用。
1. Header(头部)
头部通常包含两部分信息:
- 类型(typ),通常为
JWT
。 - 算法(alg),通常是用来签名的算法,如
HS256
、RS256
等。
一个典型的 Header 会像这样:
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload(有效负载)
有效负载是 JWT 的第二部分,包含了声明(Claims)。声明是关于实体(通常是用户)及其他数据的陈述。声明可以分为三类:
签名是 JWT 的第三部分。签名用于验证消息在传输过程中是否被篡改,确保发送方的身份。
签名是通过以下步骤生成的:
3. Signature(签名)
- 注册声明(Registered claims):这些是 JWT 中预定义的字段,不是强制的,但有助于提供一组有用的信息。例如:
iss
(发行者),exp
(过期时间),sub
(主题)等。 - 公共声明(Public claims):这些是可以自定义的声明,必须避免冲突。
- 私有声明(Private claims):这些是由应用程序定义的声明,通常用于在双方之间共享信息。
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
sub
:主题,通常是用户的 ID。name
:用户的名称。iat
:签发时间,表示这个 JWT 被创建的时间(Unix 时间戳格式)。
获取头部和有效负载的 Base64Url 编码。
用这些编码后的字符串和一个密钥、以及头部中指定的算法生成签名。
一个完整的 JWT 看起来类似这样(由三部分组成,每部分之间用 .
隔开):
eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
其中:
- 第一部分:是 Header 的 Base64Url 编码。
- 第二部分:是 Payload 的 Base64Url 编码。
- 第三部分:是签名。
JWT 常见的使用场景包括:
身份验证(Authentication):
- 在用户登录后,生成一个 JWT,返回给用户。
- 用户通过附带此 JWT(通常放在 HTTP 请求的 Authorization Header 中)进行后续请求,服务器根据 JWT 验证用户身份。
信息交换(Information Exchange):
- JWT 可以在两方之间安全地传递信息,因为签名可以确保数据的完整性。
单点登录(SSO):
- JWT 可以在多个应用间共享用户身份,适用于单点登录场景。
JWT 的优点
- 无状态性:JWT 是自包含的,意味着它包含了所有的用户信息,服务器无需保存会话状态。
- 跨平台支持:JWT 是 JSON 格式的,可以在不同语言和平台之间传输。
- 高效:JWT 通常是一个 URL 安全的字符串,非常适合在 HTTP 请求中传递,尤其适合 API 调用。
安全性注意事项
- 密钥管理:确保你的签名密钥保密,不要在客户端暴露。
- 使用 HTTPS:通过 HTTPS 传输 JWT,以防止中间人攻击。
- Token 过期时间:给 JWT 设置合理的过期时间(
exp
),避免长期有效的 Token 被滥用。
总结
JWT 是一种非常灵活且强大的标准,用于身份验证和信息交换。它可以用于 API 的认证、Web 应用的用户登录、以及多平台之间的安全通信。在使用 JWT 时,务必关注密钥管理、Token 的过期策略以及 Token 的安全传输。