Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
JWT
jwt由.号分隔的三部分组成,第一部分我们称它为头部(header),第二部分我们称其为载荷(payload),第三部分是签名(signature)。
示例:xxxxx.yyyyy.zzzzz
Header
jwt的头部承载两部分信息:
- 声明类型:这里是jwt;
 - 声明加密的算法:通常直接使用 HMAC SHA256。
 
完整的头部就像下面这样的JSON:
{
  "alg": "HS256",
  "typ": "JWT"
}
然后进行base64编码,构成了第一部分。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:
- 标准中注册的声明;
 - 公共的声明;
 - 私有的声明。
 
标准中注册的声明 (建议但不强制使用) :
- iss: jwt签发者;
 - sub: jwt所面向的用户;
 - aud: 接收jwt的一方;
 - exp: jwt的过期时间,这个过期时间必须要大于签发时间;
 - nbf: 定义在什么时间之前,该jwt都是不可用的.;
 - iat: jwt的签发时间;
 - jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
 
公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。
私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
定义一个payload:
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
然后将其进行base64编码,得到Jwt的第二部分。
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Signature
jwt的第三部分是一个签名信息,这个签名信息由三部分组成:
- header (base64后的)
 - payload (base64后的)
 - secret
 
这个部分需要base64编码后的header和base64编码后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
生成的Signature为
nuHomjWUwAeeGBK-bDGl_xL7Cx-SjRnZEjSQzbvMZF4
将这三部分用.连接成一个完整的字符串,构成了最终的jwt。
标准携带方式
一般是在请求头里加入Authorization,并加上Bearer 标注:
'Authorization': 'Bearer ' + token
验证
- 通过base64解码payload,验证iss(key),为空或不正确返回403;
 - 验证payload中的exp(过期时间戳),为空或过期返回403;
 - 通过对第一二段字符串拼接,再次根据数据库中次key对应的secret进行HS256加密,与token中的第三段字符串进行比对,不一致返回403。
 
引用