JWT
概念
JWT 主要用于用户登录鉴权,JWT (全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
数据结构
-
标头(Header)
- {
“alg”:“HS256”,
“typ”:“JWT”
}
- {
-
有效载荷(Payload)
JWT 第二部分是 Payload,也是一个 Json 对象,除了包含需要传递的数据,还有七个默认的字段供选择。iss (issuer):签发人/发行人
sub (subject):主题
aud (audience):用户
exp (expiration time):过期时间
nbf (Not Before):生效时间,在此之前是无效的
iat (Issued At):签发时间
jti (JWT ID):用于标识该 JWT
如果自定义字段,可以这样定义:
{
//默认字段
"sub":"主题123",
//自定义字段
"name":"java技术爱好者",
"isAdmin":"true",
"loginTime":"2021-12-05 12:00:03"
}
- 签名(Signature)
JWT 第三部分是签名。是这样生成的,首先需要指定一个 secret,该 secret [秘钥]仅仅保存在服务器中,保证不能让其他用户知道。这个部分需要 base64URL 加密后的 header 和 base64URL 加密后的 payload 使用 . 连接组成的字符串,然后通过header 中声明的加密算法 进行加盐secret组合加密,然后就得出一个签名哈希,也就是Signature,且无法反向解密; - 形式:xxxx.yyyy.zzzz Header.Payload.Signature
缺陷
jwt不能很好的保存用
服务器不会保存会话状态,强制用户下线的话;
不能传递敏感信息;
头部核载和签名
安全性没法保证,所以 jwt 里不能存储敏感数据。因为 jwt 的 payload 并没有加密,只是用 Base64 编码而已。
无法中途废弃。因为一旦签发了一个 jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的 jwt 过期后重新签发新的 jwt。
续签问题。当签发的 jwt 保存在客户端,客户端一直在操作页面,按道理应该一直为客户端续长有效时间,否则当 jwt有效期到了就会导致用户需要重新登录。那么怎么为 jwt 续签呢?最简单粗暴就是每次签发新的 jwt,但是由于过于暴力,会影响性能。如果要优雅一点,又要引入 Redis 解决,但是这又把无状态的 jw t硬生生变成了有状态的,违背了初衷。
JWT的优点
json格式的通用性,所以JWT可以跨语言支持,比如Java、JavaScript、PHP、Node等等。
可以利用Payload存储一些非敏感的信息。
便于传输,JWT结构简单,字节占用小。
不需要在服务端保存会话信息,易于应用的扩展。