Jwt
Json Web Token(Jwt)
1.Jwt介绍
JSON Web Token,简称 JWT,读音是 [dʒɒt]( jot 的发音),是一个基于 RFC 7519 的开放数据标准,它定义了一种宽松且紧凑的数据组合方式。其作用是:JWT是一种加密后数据载体,可在各应用之间进行数据传输。
互联网服务离不开用户认证。一般流程是下面这样。
1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入用户的 Cookie。
4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。
这种模式的问题在于,扩展性(scaling)不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。
举例来说,A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?
一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败。
另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。
2.Jwt组成
2.1 Jwt结构
以 . 分隔分为三个部分.
1 | |
2.2 Jwt令牌验证方式
- 获取 JWT:从HTTP请求中获取JWT令牌。
- 解析 JWT:使用工具类将JWT令牌解析成头部、载荷和签名三个部分。
- Base64 解码:对获取的JWT头部和载荷部分进行Base64解码,得到原始的 JSON 格式数据。(注意头部和载荷只是使用Base64编码这个是可逆的)
- 验证签名:使用相同的算法、服务器自己的密钥和获取的Jwt头部、载荷部分,重新计算签名。
- 比较签名:将重新计算得到的签名与JWT中的签名进行比较。如果两者一致,则认为JWT是有效的,否则认为JWT是无效的。
3.Jwt的特性
3.1无状态性
JWT 不需要在服务端存储任何状态,客户端可以携带 JWT 来访问服务端,从而使服务端变得无状态。这样,服务端就可以更轻松地实现扩展和负载均衡。
传统登录(有状态性):
登录过程:用户提供用户名和密码,认证服务器验证用户身份,并在服务器端创建一个会话。通常,服务器生成一个会话标识符(session ID),将该标识符发送给客户端。
状态存储:服务器端存储有关用户的会话信息,包括用户身份、权限、登录状态等。会话信息可以存储在服务器的内存、数据库或其他持久化存储中。
后续请求:客户端在后续的请求中携带会话标识符,服务器通过该标识符识别并验证用户的身份,维护用户的登录状态。
JWT(无状态性):
登录过程:用户提供用户名和密码,认证服务器验证用户身份后,生成一个包含用户信息的JWT,并将该JWT发送给客户端。
状态存储:服务器不需要在后端存储用户的会话状态。JWT 是自包含的,包含了用户信息和签名,服务器无需存储额外信息。
后续请求:客户端在后续的请求中携带JWT,服务器通过验证JWT的签名来确认用户的身份,无需再次查询数据库或维护会话状态。
3.2 可自定义
JWT 的载荷部分可以自定义,可以存储任何 JSON 格式的数据。这意味着我们可以使用 JWT 来实现一些自定义的功能,例如存储用户喜好、配置信息等等。
3.3 扩展性强
JWT 有一套标准规范,因此很容易在不同平台和语言之间共享和解析。此外,开发人员可以根据需要自定义声明(claims)来实现更加灵活的功能。
3.4 调试性好
JWT 有一个简单而可读的结构,由三部分组成:头部、载荷和签名。每个部分都是Base64编码的JSON字符串,这使得开发人员能够轻松查看 JWT 的内容,了解其中包含的信息。
3.5 安全性取决于密钥管理
JWT 的安全性取决于密钥的管理。如果密钥被泄露或者被不当管理,他人就可以通过密钥自行生成所需的Jwt,来代替用户执行其他非法操作,因此,在使用 JWT 时,一定要注意密钥的管理,包括生成、存储、更新、分发等等。
3.6 无法撤销
由于 JWT 是无状态的,一旦 JWT 被签发,就无法撤销。如果用户在使用 JWT 认证期间被注销或禁用,那么服务端就无法阻止该用户继续使用之前签发的 JWT。因此,开发人员需要设计额外的机制来撤销 JWT,例如使用黑名单或者设置短期有效期等等。
3.7 需要缓存到客户端
当客户端向认证服务器发送登录请求以及所需信息时,返回给用户的Jwt一般需要客户端缓存,这意味着 他人有可能窃取用户的Jwt进行登录操作。
3.8 载荷大小有限制
由于 JWT 需要传输到客户端,因此载荷大小也有限制。一般不建议载荷超过 1KB,会影响性能。
4.Jwt的优缺点
4.1 优点
无状态:JWT 本身不需要存储在服务器上,因此可以实现无状态的身份验证和授权。
可扩展性:JWT 的载荷可以自定义,因此可以根据需求添加任意信息。
可靠性:JWT 使用数字签名来保证安全性,只要因此具有可靠性。
跨平台性:JWT 支持多种编程语言和操作系统,因此具有跨平台性。
高效性:由于 JWT 不需要查询数据库,因此具有高效性。
PS:
无状态性:集群模式的横向扩展(多个服务器)上,传统登录需要考虑多台服务器用户会话信息的数据同步问题,因为服务器需要用户会话信息认证,而Jwt则无需考虑,因为Jwt每个请求都包含了所有必要的信息,无需在集群中共享会话状态。
高效性: 如下图所示 当客户端通过认证服务器获取Jwt之后,之后在Jwt生效的时段中都可以直接进行Jwt验证,免去了与数据库的交互

4.2 缺点
安全性取决于密钥管理:JWT 的安全性取决于密钥的管理,如果密钥被泄露或者被不当管理,那么 JWT 将会受到攻击。
无法撤销令牌:由于 JWT 是无状态的,一旦 JWT 被签发,就无法撤销。
需要传输到客户端:由于 JWT 包含了用户信息和授权信息,因此 JWT 需要传输到客户端,这意味着 JWT 有被攻击者窃取的风险,比如重放攻击。
载荷大小有限制:由于 JWT 需要传输到客户端,因此载荷大小也有限制。
PS:
重放攻击: 攻击者截获并重复使用先前传输的有效消息或令牌的攻击方式。在JWT的场景下,如果攻击者能够截获有效的JWT并在有效期内重复使用,这可能导致一些安全问题。