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
3
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 //头部
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ //载荷
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c //签名

2.2 Jwt令牌验证方式

  1. 获取 JWT:从HTTP请求中获取JWT令牌。
  2. 解析 JWT:使用工具类将JWT令牌解析成头部、载荷和签名三个部分。
  3. Base64 解码:对获取的JWT头部和载荷部分进行Base64解码,得到原始的 JSON 格式数据。(注意头部和载荷只是使用Base64编码这个是可逆的)
  4. 验证签名:使用相同的算法、服务器自己的密钥和获取的Jwt头部、载荷部分,重新计算签名。
  5. 比较签名:将重新计算得到的签名与JWT中的签名进行比较。如果两者一致,则认为JWT是有效的,否则认为JWT是无效的。

3.Jwt的特性

3.1无状态性

JWT 不需要在服务端存储任何状态,客户端可以携带 JWT 来访问服务端,从而使服务端变得无状态。这样,服务端就可以更轻松地实现扩展和负载均衡。

传统登录(有状态性)

  1. 登录过程:用户提供用户名和密码,认证服务器验证用户身份,并在服务器端创建一个会话。通常,服务器生成一个会话标识符(session ID),将该标识符发送给客户端。

  2. 状态存储:服务器端存储有关用户的会话信息,包括用户身份、权限、登录状态等。会话信息可以存储在服务器的内存、数据库或其他持久化存储中。

  3. 后续请求:客户端在后续的请求中携带会话标识符,服务器通过该标识符识别并验证用户的身份,维护用户的登录状态。

JWT(无状态性):

  1. 登录过程:用户提供用户名和密码,认证服务器验证用户身份后,生成一个包含用户信息的JWT,并将该JWT发送给客户端。

  2. 状态存储:服务器不需要在后端存储用户的会话状态。JWT 是自包含的,包含了用户信息和签名,服务器无需存储额外信息。

  3. 后续请求:客户端在后续的请求中携带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并在有效期内重复使用,这可能导致一些安全问题。


Jwt
http://example.com/2024/01/30/Jwt/
作者
kangkang
发布于
2024年1月30日
许可协议