OAuth协议中说到的AccessToken能够是如下两种:html
1.任意只起到标识做用的字符串:这种状况下Resource Server处理请求时须要去找Authorization Server获取用户信息。算法
2.携带用户基本信息的加密字符串:这种状况下Resource Server处理请求时只需解析AccessToken,直接获取到用户信息便可。缓存
JWT就是用来生成第二种access token的一种协议。具体介绍:JWT安全
具体来讲,一个JWT token就是以下一串字符串:服务器
这个字符串由3部分(Header, Payload, Signature)组成,用"."分隔。编码
Header加密
这一部分时用来定义构造JWT的参数信息,用一个JSON对象表示以下:spa
{ "alg": "HS256",//定义JWT中的Signature所用的算法 "typ": "JWT"//表示Token的类型,此处统一写成JWT }
将上述JSON对象的字符串形式进行Base64Url编码以后就获得了token中的header部分。code
Payloadserver
这一部分是存储业务信息的地方。信息也以JSON对象的方式表示:
{ "iss": "Jensen",//签发人 "exp": "1308726283"//token过时时间戳 }
对象中的key其实能够为任意字符串。可是为了让token字符串尽量小。key尽可能统一为3各字符。而后为了将一些经常使用的key标准化,JWT定义了以下标准key:
iss (issuer):签发人
exp (expiration time):过时时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
详见 RFC7519
固然咱们也能够定义本身的key,好比:name:姓名,admin:是否为admin...
将上述JSON对象的字符串形式进行Base64Url编码以后就获得了token中的payload部分。
Signature
将header和payload部分的base64字符串用特定的密钥进行hash获得签名部分。好比咱们选用HMAC SHA256
做为签名算法,则签名过程以下:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
secret
只有服务器端才知道,经过签名能够防止token被修改。
与OAuth验证结合
采用这种方式生成的access token, Resouce Server处理请求的时候(access token能够放在Authorization Header中,好比:Bearer xxxx)能够直接解析。可是这里有两个问题:1. Authorization Server和Resource Server如何共享签名的secret?最简单的方法就是Resource Server和Authorization Server使用统一的secret。可是这样的话若是有不少Resource Server(好比不一样的资源提供者)共用一个AuthorizationServer的话可能就有安全问题,这种状况下就须要针对不一样的resource server使用不一样的secret进行签名了。同时client在申请token的时候也须要告知要访问那个resource server。2. Token的失效问题由于Token是在Resource Server直接解析,意味着一旦签发,在其到期前一直有效。用户logout后也没办法将已经产生的token设置为无效。要解决这个问题,仍是须要Resource Server将access token提交至Authorization Server验证。Authorization Server能够将access token进行缓存或者缓存采用相关算法为其生成的key(好比用签名做为key),验证时只需验证key是否存在便可。(固然,咱们我进行失效处理时能够把缓存的key删掉便可)