JWT介绍
定义
JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。由于该信息经过数字签名,因此可以被验证和信任。
结构
JWT的紧凑形式由三部分组成,每部分经过Base64Url编码后以点号( . )连接,分别是:
Header( 头部 )
包含令牌类型 ( typ ) 和签名算法 ( alg ) ,例如:1
2
3
4{
"alg": "HS256",
"typ": "JWT"
}该JSON经过Base64Url编码,形成 JWT 的第一部分( 如 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 )。
Payload( 载荷 )
包含声明 ( claims ) ,即需要传递的数据。声明分为三类:- Registered Claims(注册声明)(非强制但推荐使用):
- Public Claims(公共声明):可自定义,但需避免冲突(建议使用 IANA 注册或 URI 命名空间)。
- Private Claims(私有声明):双方协商的自定义数据。
示例:
1
2
3
4
5{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
该 JSON 会经过 Base64Url 编码,形成 JWT 的第二部分( 如 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ )。签名仅防篡改,不加密!头部和载荷信息可被任何人解码查看,敏感数据需额外加密。
Signature( 签名 )
用于验证令牌完整性和真实性。生成方式依赖头部指定的算法:- HMAC SHA256 示例:
1
2
3
4HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secretKey
)- RSA 示例(使用私钥签名,公钥验证):
1
2
3
4RSASHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
privateKey
)签名结果经过 Base64Url 编码,形成 JWT 的第三部分(如 SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)。
完整JWT示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
解码后
- Header: {“alg”:”HS256”,”typ”:”JWT”}
- Payload: {“sub”:”1234567890”,”name”:”John Doe”,”iat”:1516239022}
- Signature: 使用密钥验证前两部分是否被篡改
使用场景
Authorization ( 授权 )
JWT 最常见的用途。用户登录后,每个后续请求都会携带 JWT,允许用户访问与该令牌匹配的路由、服务和资源。如今,单点登录(Single Sign-On, SSO) 广泛使用 JWT,因为它开销小,且能轻松跨域使用。Information Exchange ( 信息交换 )
JWT 是在各方之间安全传输信息的一种优秀方式。由于 JWT 可以签名(例如使用公私钥对),因此可以确保发送者的身份真实可信。此外,由于签名是基于头部(header)和载荷(payload)计算的,还能验证内容是否被篡改。
工作原理
在身份验证过程中,当用户使用凭据成功登录后,系统会返回一个 JSON Web Token(JWT)。由于令牌本身就是凭证,必须格外注意防范安全问题。一般来说,令牌的保存时间不应超过必要期限。同时,由于浏览器存储缺乏安全性,不应在其中保存敏感的会话数据。
当用户需要访问受保护的路由或资源时,用户代理(如浏览器)应当发送 JWT,通常是通过 Authorization 头部使用 Bearer 模式进行传输。头部内容格式如下:
1 | Authorization: Bearer <token> |
在某些情况下,这可以成为一种无状态的授权机制。服务器的受保护路由会检查 Authorization 头部中的有效 JWT,如果存在有效令牌,则允许用户访问受保护资源。如果JWT包含必要数据,可能会减少某些操作对数据库查询的需求,不过实际情况可能有所不同。