avatar

JWT的介绍和优缺点

JWT的详细介绍

什么是JWT

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSAECDSA的公钥/私钥对对JWT进行签名

(摘抄自官网)

使用场景

  • 授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。
  • 信息交换:JWT是在各方之间安全地传输信息的一种好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确保发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否遭到篡改。

令牌结构

JWT通常都是由三部分组成,这些部分由点(.)分隔

JWT通常如下所示为 xxxxx.yyyyy.zzzzz

Header(标头)

标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。

例如

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

然后,此JSON被Base64Url编码以形成JWT的第一部分。

Payload(有效载荷)

令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。

注意!!!

请注意,对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将机密信息放入JWT的有效负载或报头元素中。

Signature(签名)

要创建签名部分,您必须获取编码的标头,编码的有效负载,机密,标头中指定的算法,并对其进行签名。

例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者是它所说的真实身份。

验证的流程

  1. 客户端向服务端发起登录请求
  2. 服务端生成secret,使用令牌的类型和签名算法生成header,生成payload
  3. 通过secret和header、payload与签名算法生成JWT,返回给客户端
  4. 之后客户端每次就在请求头中携带此JWT
  5. 服务端收到客户端携带JWT的请求后,会通过Base64解码,获取header与payload,再将保存在服务端的secret与其再加密一次,如果哦和signature一致,则验证通过。

同等的技术,他有什么优势

  1. 无状态管理,JWT中就自包含了验证的所有信息,不需要服务端存储额外的session,节省了空间。
  2. 适合单点登录,对多系统和分布式系统的支持很友好。

有没有缺点

注销登录以及修改密码

注销登录以及修改密码的时候,token依然有效。所以即使客户端删除了 jwt,但是该 jwt 还是在有效期内,只不过处于一个游离状态

解决方案:

  1. 将secret清空或修改成与用户属性相关。这样在用户修改密码时,原secret就消失,自然就无法完成校验
  2. 借助第三方工具管理jwt的状态(但是这点设计与JWT的初衷相违背)

续签问题

假如每登录一次就要延迟一次有效时间。如果是session,一般的做法是直接将该session的有效期延迟30分钟。而 jwt 本身的 payload 之中也有一个 exp 过期时间参数,但是没有办法对其修改,如果强行修改则signature也会发生变化。

解决方案:

  1. 每次请求刷新 jwt。非常暴力,但是性能不好,每次请求都携带并且修改,浪费太多的资源
  2. 使用 redis 记录独立的过期时间。我们在 redis 中单独会每个 jwt 设置了过期时间,每次访问时刷新 jwt 的过期时间,若 jwt 不存在与 redis 中则认为过期。

总结

JWT不能滥用,因为存在需要的问题。而传统的session+cookie机制反而能做的更好。

如果是简单的认证,对会话管理的要求不高的项目其实是可以使用的。

文章作者: Hobo
文章链接: https://hobo-clh.github.io/2020/12/02/JWT%E7%9A%84%E4%BB%8B%E7%BB%8D%E5%92%8C%E4%BC%98%E7%BC%BA%E7%82%B9/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hobo's blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论