5

什么是JWT?

JWT(JSON Web Token)是一种用于在各方之间安全地传输信息的紧凑、自包含的令牌格式。JWT是一种基于JSON的标准,定义了一种简洁的方式来表示请求方和提供方之间的验证信息。它通常用于Web应用的身份验证和授权。

image.png

基于Session的认证流程

web服务离不开用户认证。一般流程是下面这样。

image.png

Session存在的问题

  • 多台服务器共享问题:如果系统部署在多台服务器上(例如在负载均衡的情况下),每台服务器都需要能够访问所有的session数据。这就要求这些服务器之间共享session信息。

第一种解决方案

session复制,在这种方法中,每当用户的session在某台服务器上创建或更新时,session数据都会被复制到集群中的其他服务器上。因此,无论用户的请求被负载转发到哪台服务器,这些服务器都可以访问相同的session数据

image.png
这样对服务器不太友好,每个人只需要保存自己的 session id,而服务器要保存所有人的 session id !如果访问服务器多了, 就得由成千上万,甚至几十万个。

第二种解决方案

就是使用服务器来存储session_id。这个想法是将所有的session数据集中存储在这台服务器中,所有服务器都去访问同一个存储位置来获取session数据。这样一来,避免了在不同服务器之间复制session数据的麻烦。

image.png

这样也存在一种问题,就是当这个session存储的服务器挂了所以session全部失效,必须全部重新登录

使用JWT

可以换种思路上,不一定需要进行存储session,而是在存在客户端存储,可是如果不保存这些 session id, 怎么验证客户端发给我的 session id 的确是我生成的呢,如果不去验证,我们都不知道他们是不是合法登录的用户。

JWT的结构

一个JWT通常由三部分组成:Header(头部)、Payload(负载)和Signature(签名),它们通过.分隔开来。

1. Header

Header通常包括两部分:令牌类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。Header的JSON形式如下:

{
  "alg": "HS256",
  "typ": "JWT"
}

将上述JSON数据进行Base64Url编码后,得到JWT的第一部分。

2. Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

还可以定义私有字段

{
  "username": "mengyunzhi",
  "name": "yunzhi",
  "role": "admin"
}

JWT 默认是不加密的,任何人都可以读到,所以不要把敏感信息(password或重要的个人身份信息)放在这个部分。

这个 JSON 对象也要使用 Base64URL 算法转成字符串。

3. Signature

Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VybmFtZSI6Im1lbmd5dW56aGkiLCJuYW1lIjoieXVuemhpIiwicm9sZSI6ImFkbWluIn0.
Gecz5qFrimEVsxTIEvsgBvhEyyX2acr88YkT0ec-VGI

image.png

4. Base64URL

为什么P要使用Base64URL进行加密算法

JWT 作为一个令牌(token),有时候会放上在 URL。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。

www.mengyunzhi.com/?token=xxxx

JWT 的使用方式

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。一般是放在 HTTP 请求的头信息Authorization字段里面。

Authorization: Bearer <token>

总结

相比于传统的基于Session的身份验证方法,JWT具有以下几个优势:

无状态:JWT不需要在服务器端存储用户会话数据,令牌本身包含了所有必要的用户信息。

适用分布式:由于JWT在客户端持有,而不依赖于服务器进行session存储,因此在多个服务器或微服务之间传递用户身份信息时,JWT更为方便。

减少服务器负载:服务器不需要为每个用户维护Session数据,减轻了服务器的存储压力,特别是在大量用户同时访问的情况下。

参考文章

https://learnku.com/articles/30051


kexb
474 声望15 粉丝

引用和评论

0 条评论