欢迎关注微信公众号:全栈工厂
本文主要参考
1. 简介
JSON Web Token(JWT)是一种基于开放标准RFC 7519设计,使用HMAC或RSA算法签名的无状态授权令牌;由于令牌本身包含了授权所需要的所有信息,因此JWT非常适合分布式的单点服务授权认证。
一个JWT通常由三部分组成:头部(Header)、消息体(Payload)、签名(Signature),大致结构如下图所示:
1.1 头部(Header)
头部一般情况下主要包含两部分信息:
- 令牌类型(typ):例如 jwt;
- 签名算法(alg):令牌签名所使用的算法,例如SHA256、RSA等。
所以一个JWT的header值通常为:
header = base64UrlEncode('{"alg":"SHA256","typ":"JWT"}')
1.2 消息体(Payload)
如果我们认为一个JWT令牌是合法的,那么我们就会从JWT的消息体里面提取令牌的身份信息,这样我们就会知道是谁在使用这个令牌以及令牌是否过期等信息;因此消息体里主要包含令牌的所有实体信息,用户可以自己决定要放那些信息到消息体里面。
所以一个JWT的payload值可以为:
payload = base64UrlEncode('{ "exp": "1518087620","name": "John Doe","id":"2"}')
表示该令牌的授权人名称是:John Doe,授权人id是:2,令牌过期时间是:1518087620。
1.3 签名(Signature)
签名部分主要用于验证一个JWT令牌的合法性,验证过程非常简单:
- 从header中提取出签名所使用的算法(例如SHA256);
- 获取服务端在对Token进行签名时所使用的key;
- 使用签名算法以及key重新计算签名
SHA256(header + "." + payload, key)
;- 对比新生成的签名和用户提交上来的签名是否一致,完全一致则令牌合法。
2. 总结
2.1 优点
1. 紧凑的设计,方便令牌的存储和传输
JWT的结构设计让它占用的空间更小,可自定义的消息体还可以让令牌存储额外的非敏感信息,简单实用。
2. 无状态的授权认证,方便应用扩展
JWT的无状态特性让服务的横向扩展变得更加简单,服务端不再需要解决类似Session共享等授权信息同步问题。
3. 统一的JSON对象,方便跨平台使用
JWT的header和payload存储的都是JSON对象,因此任何平台的任何语言都可以很方便的进行验证使用。
2.2 缺点
1. 如果令牌泄漏,服务端对令牌的使用失去控制
由于服务端并不存储令牌,如果一个JWT令牌被黑客窃取,除非借助其他技术手段,否则在该令牌有效期内,黑客可以随意使用该令牌,服务端甚至很难发现该令牌已经被窃取。
2. 令牌信息容易暴露,令牌安全完全取决于签名key
JWT令牌的header和payload看起来是一串随机字符串,实际上只是用base64进行编码了而已,用户可以通过使用base64对其解码看到令牌签名所使用的算法以及payload中所存储的授权用户信息;这样黑客就有可能通过header中所标注的签名算法对令牌的签名进行暴利破解,如果签名key被破解出来,那么黑客便可以随意生成自己的JWT令牌,后果不堪设想!因此签名算法中所使用的key极为关键。
注:文中如有任何错误,请各位批评指正!