Skip to content

JWT

什么是JWT?

JWT 即Json Web Token,将用户登录态以及数据用加密的json格式存储在客户端,服务端可以完全依靠这个字符串认定用户身份。简单来说,这是一种用户身份认证的解决方案。

大致的认证过程是这样的:

  1. 客户端发送账号密码
  2. 服务端验证账号密码,返回一个JWT字符串
  3. 客户端本地保存JWT字符串
  4. 客户端带上JWT字符串访问业务接口
  5. 服务端解析JWT字符串,确定用户身份

看看跟传统的认证方式的区别

session认证过程

  1. 客户端发送账号密码
  2. 服务端验证账号密码,生成session数据,返回session id
  3. 客户端将session id保存在cookie
  4. 客户端带上session id访问业务接口
  5. 服务端查询session数据,确定用户身份

JWT最大的不同是,完全不需要中心的认证数据节点。我们知道,传统的session模式,由于每一个请求都需要session验证,session服务很容易就成为了一个系统的单点,JWT的方式从根本上避免了认证单点的存在。

JWT的实现

JWT大概的样子是这样的

{header_urlb64}.{payload_urlb64}.{signature}

header,payload,signature三个部分的字符串通过. 连接起来。

描述JWT的元数据,例如:

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

其中alg表示前面算法,默认是 HMAC SHA256(写成 HS256),typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

Payload

这里用来存放实际的数据,JWT规定了7个官方字段。

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

除了官方字段,这里还可以存放自定义的数据。例如:

{
  "user_id": 111,
  "name": "test",
  "role": "admin"
}

Signature

这个字段是对前两个字符串的签名,防止数据被篡改。签名方法如下:

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

header和payload都是json格式的字符串,在生成JWT字符串或者签名里面,需要先对原始的json字符串进行base64UrlEncode处理。

* 知识点,什么是base64UrlEncode?
Base64有三个字符+、/和=,在URL里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。
用python来描述就是:base64.urlsafe_b64encode()

SHA256需要传入一个secret作为salt,这个secret必须保管在服务器端。

总结

JWT的好处

  1. 无状态,不需要中心认证节点,避免了单点的问题,同时减少了登录态认证环节的耗时。
  2. 解决跨系统间共享登录态的问题。比如在session模式下,station,分拣系统用的同一套账户体系,但是却需要登录两次。

JWT的缺点

  1. 在颁发后无法让JWT即刻失效。例如改密码之类的操作,无法强制让该用户所有登录态失效。所以对于一些重要的接口,应该进行二次认证。