JWT的学习:JSON Web Token

维基百科是这样解释的:JSON Web Token(JWT,发音为/dʒɒt/ [1])是一个基于JSON的开放标准(RFC 7519,https://tools.ietf.org/html/rfc7519),用于创建访问令牌来声明(assert)一些claims(这里是指需要维护的信息)。 例如,服务器可以生成一个令牌,该令牌具有“以管理员身份登录”并将其提供给客户端。 然后,客户端可以使用该令牌来证明它以管理员身份登录。 令牌由服务器的密钥签名,因此客户端和服务器都能够验证该令牌是否合法。 令牌被设计为紧凑、URL安全和可用,特别是在Web浏览器单点登录(SSO)上下文中。 JWT声明通常可用于在身份提供商和服务提供商之间传递身份验证的用户身份,或业务流程所要求的任何其他类型的声明。令牌也可以被认证和加密。 JWT依赖于其他基于JSON的标准:JWS(JSON Web签名)RFC 7515和JWE(JSON Web Encryption)RFC 7516. 

JWT由三部分组成:header、payload和signature。

1.header主要指明了加密的算法,例如:header = '{"alg":"HS256","typ":"JWT"}'。

2.payload主要是负载的信息(claims)。

claims又分为几种类型:已经注册的,公有的,私有的。

claims主要是指一些关键的信息,标准中根据最常见的已经设计了一些key值,然后也允许用户自己补充。

3.signature是这样产生的:

key           = 'secretkey'(如果是非对称,则是私钥;如果是对称算法,则是对称密钥,用来对未签名的token进行签名)。
unsignedToken = encodeBase64Url(header) + '.' + encodeBase64Url(payload)
signature     = HMAC-SHA256(key, unsignedToken) 

encodeBase64Url是一种Base64的转码方式,它的意思是对这些数据进行Base64转码,用另外一种方式来显示,使得它肉眼不可读,但是它是可逆的,对于机器是可逆的,可以参考:https://zh.wikipedia.org/wiki/Base64。由此可知,这里不可以放密钥等敏感信息。

请注意Base64不是加密,MD5也不是加密。一个小插曲,当年去找工作,如果你把MD5说成加密,人家会不要你,觉得你没有搞清楚,但是现在满大街都在说MD5加密----这说明什么呢,真是无语了。

JWT的逻辑有一点像数字签名,最后对token进行了加密,生成了签名,这样保证了这段报文无法被人篡改。

这样的一个JWT由服务端会送给客户端,客户端可以对其进行验签,然后在每次请求,再会送给服务端,服务端对其进行解析,解析出有效的数据,这样就不用保存了。

这个地方涉及一些历史知识:

1.第一代保存方法,cookie保存,cookie中保存用户输入的用户名和密码,这个很不安全,容易被不良程序获得。

2.第二代保存方法,session保存,由服务端生成一个session id,这个id对应了缓存中或者数据库中的一条用户信息,服务端把session id返回给客户端,客户端每次请求,提交这个session id,这样做,服务端需要集中维护这些session,需要有一台单独的session服务器。

好处:

参考:https://ponyfoo.com/articles/json-web-tokens-vs-session-cookies。

1.可伸缩性:水平伸缩性,不需要再为了保留sessionId而维护一个session生成器。

2.对RESTful的支持良好:实际上根本不需要保存,这样真正做到了HTTP的无状态性。

参考:https://en.wikipedia.org/wiki/JSON_Web_Token。

参考:https://tools.ietf.org/html/rfc7519。

参考:http://blog.csdn.net/u012017645/article/details/53585872,这里有一些java的实现。

猜你喜欢

转载自blog.csdn.net/chaiyu2002/article/details/77343799