JWT
什么是JWT?
JWT 即Json Web Token,将用户登录态以及数据用加密的json格式存储在客户端,服务端可以完全依靠这个字符串认定用户身份。简单来说,这是一种用户身份认证的解决方案。
大致的认证过程是这样的:
- 客户端发送账号密码
- 服务端验证账号密码,返回一个JWT字符串
- 客户端本地保存JWT字符串
- 客户端带上JWT字符串访问业务接口
- 服务端解析JWT字符串,确定用户身份
看看跟传统的认证方式的区别
session认证过程
- 客户端发送账号密码
- 服务端验证账号密码,生成session数据,返回session id
- 客户端将session id保存在cookie
- 客户端带上session id访问业务接口
- 服务端查询session数据,确定用户身份
JWT最大的不同是,完全不需要中心的认证数据节点。我们知道,传统的session模式,由于每一个请求都需要session验证,session服务很容易就成为了一个系统的单点,JWT的方式从根本上避免了认证单点的存在。
JWT的实现
JWT大概的样子是这样的
{header_urlb64}.{payload_urlb64}.{signature}
header,payload,signature三个部分的字符串通过.
连接起来。
Header
描述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的好处
- 无状态,不需要中心认证节点,避免了单点的问题,同时减少了登录态认证环节的耗时。
- 解决跨系统间共享登录态的问题。比如在session模式下,station,分拣系统用的同一套账户体系,但是却需要登录两次。
JWT的缺点
- 在颁发后无法让JWT即刻失效。例如改密码之类的操作,无法强制让该用户所有登录态失效。所以对于一些重要的接口,应该进行二次认证。