Web验证方式(4)--JWT

OAuth协议中说到的AccessToken可以是以下两种:

1.任意只起到标识作用的字符串:这种情况下Resource Server处理请求时需要去找Authorization Server获取用户信息。

2.携带用户基本信息的加密字符串:这种情况下Resource Server处理请求时只需解析AccessToken,直接获取到用户信息即可。

JWT就是用来生成第二种access token的一种协议。具体介绍:JWT

具体来说,一个JWT token就是如下一串字符串:

 

这个字符串由3部分(Header, Payload, Signature)组成,用"."分隔。

Header

这一部分时用来定义构造JWT的参数信息,用一个JSON对象表示如下:

{
  "alg": "HS256",//定义JWT中的Signature所用的算法
  "typ": "JWT"//表示Token的类型,此处统一写成JWT
}

 将上述JSON对象的字符串形式进行Base64Url编码之后就得到了token中的header部分。

Payload

这一部分是存储业务信息的地方。信息也以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(比如不同的资源提供者)共用一个Authorization
Server的话可能就有安全问题,这种情况下就需要针对不同的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删掉即可)
posted @ 2018-08-21 22:59  self.refactoring  阅读(204)  评论(0编辑  收藏  举报