你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
JWT 是一种开放的标准(RFC 7519),用于在各方之间以一种紧凑且安全的方式传输信息。它特别适用于分布式系统中无状态认证场景,比如单点登录(SSO)。
JWT 的格式是一个由三部分组成的字符串,使用点(.)分隔:
Header.Payload.Signature
Header 包含两个部分:
类型:通常为 JWT。
签名算法:如 HMAC-SHA256 或 RSA。
示例:
{
"alg": "HS256",
"typ": "JWT"
}
Base64 编码后:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload 包含声明(Claims),用于存储需要传递的信息。这些声明分为三类:
注册声明(Registered Claims):如 iss(签发者)、exp(过期时间)、sub(主题)等。
公共声明(Public Claims):自定义的公共信息,需避免与注册声明冲突。
私有声明(Private Claims):双方协商使用的字段。
示例:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
Base64 编码后:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0
Signature 是为了验证消息的完整性和发出者的真实性。计算方式如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
示例:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
用户认证:用户通过用户名和密码登录,服务器验证成功后生成 JWT,并返回给客户端。
传递 JWT:客户端通常将 JWT 存储在浏览器的 LocalStorage 或 Cookie 中,每次请求时附带在 HTTP Header 中(如 Authorization: Bearer <token>)。
验证 JWT:服务器收到请求后,解析并验证 JWT 的签名与有效期等信息,无需保存用户状态即可完成认证。
无状态:服务器不需要保存会话信息,适合分布式架构。
紧凑性:数据经过 Base64 编码后体积小,便于传输。
可扩展性:可以在 Payload 中存储额外的数据(如角色信息)。
安全性:支持签名和加密,防止篡改和伪造。
不能主动失效:JWT 签发后即便用户退出登录,JWT 本身仍然有效,需等待过期。
体积较大:与传统的 Session ID 相比,JWT 的大小可能更大,占用带宽。
泄露风险:一旦 JWT 被窃取,攻击者可冒充用户,除非服务器实现了 Token Blacklist(黑名单)。
用户认证:
用户登录成功后获取 JWT,后续每次请求带上 Token,服务器无需存储用户状态。
单点登录(SSO):
各个子系统共享 JWT 实现跨系统认证。
API 安全访问:
为 RESTful API 提供无状态的访问控制。
使用 HTTPS:
确保通信过程中 JWT 不被窃取。
设置合理的过期时间:
使用 exp 声明限制 Token 的有效期。
定期更换密钥:
更新签名密钥,防止被长期使用。
验证来源和完整性:
验证 iss(签发者)和签名,防止伪造。
Token Blacklist:
针对登出或被盗的 JWT,可采用黑名单机制使其失效。
如何解决 Token 主动失效?
可以在服务器存储黑名单或结合 Redis 缓存机制。
JWT 与 Session 的区别?
Session 需要服务器存储状态,而 JWT 是无状态的。
JWT 能否完全取代 Session?
对于需要实时性操作(如强制下线),JWT 可能不足,需结合其他机制补充。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!