Token之关于JWT(二)
这一部分想写点理论。
Token的创建标准,据我跟程序员大大们聊过,常用的标准是JWT(JSON Web Tokens),很多语言都支持!
那老方式,提问!
Q:啥是jwt?(自己翻译的,网上找的好多语句不通。有不对的地方请指正!)
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
(JSON Web Token(JWT)是一个开放式标准(RFC7519)它定义了一个紧凑的以及自包含的方式,使得通信各方以JSON对象安全的传输信息。因为有了数字签名所以这样的信息是可被验证和信任的。可以使用secret(使用HMAC算法时)或使用RSA/ECDSA的公用/专用的密钥对,对JWTs进行签名。)
Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
(尽管可以对JWTs进行加密来提供双方的保密性,但我们将更关注已经被签名的令牌。已签名的令牌还可以验证其中包含的声明的完整性,对其他方来讲,已加密的tokens隐藏了他们所包含的声明。当使用公用/专用的密钥对对tokens进行签名时,签名还能证明只有持有私钥的一方才是对tokens签发的一方。)
引用了网上一个通俗易懂的答案(https://www.xuebuyuan.com/840264.html):
(我又补充了一下)
self-contained:自己有足够的信息来说明自己是干什么的并且能够以独立的方式给外界调用
self-describing:自己能把自己描述清楚自己是什么,不需要补充额外的描述信息和配置文件
当然JSON Web Tokens的结构是什么呢?
形态很简洁紧凑,JSON Web Tokens由三部分组成并以‘.’(dots)分割,他们是:
Header,Payload,Signature.
因此,JWT看上典型就是这样:xxxxx.yyyyy.zzzzz
那我们分别来看每一部分:
第一部分Header:
Header典型包含的两部分,一个是token的类型,另一个就是正在使用的签发算法,例如:HMAC SHA256或者RSA
然后这部分就会被base64url进行编码组成JWT的第一部分。
第二部分就是Payload,这部分包含了声明信息,声明信息陈述的是关于一个实体(典型的:指用户)和附加数据。(Payload吧,我看有人翻译成荷载,这里我就不翻译了,翻译的奇怪。)声明信息一共有三种类型:已注册的,公用的和私有的。
已注册声明:这是一系列预定义的声明(claims),并不是强制性的,但建议使用,用来提供一组有用的,可互相通用的声明。其中包含:iss(发行者),exp(到期时间戳),sub(主题),aud(受众)和其他。(值得注意的是声明names只能是三个字母长,就像是JWT意味着简洁紧凑)
公用声明:当大家使用JWTs的时候可以自定义,但是为了避免冲突使用者应该在IANA JSON Web Token注册处中定义它或者作为一个URI在包含抗冲突的命名空间中定义。
私有声明:是作为自定义的声明被创造出来的,从而各方之间共享信息并协商一致使用,它们并不是已注册的也不是公用声明。
举例:Payload包含的信息有:
然后这个payload会进行Base64url编码,组成JWT的第二部分。
!!!一定注意:对于已签名的tokens的这部分信息来说,尽管已被保护防止篡改,但任何人还是可以读取。除非对其进行加密,否则请不要再payload或者报头元素中放入机密信息。
第三部分签名(Signature):
要创建签名部分你必须要取得编码后的header,编码后的payload,一个secret(类似于私钥?加盐组合加密。),header中指定的算法,并对其签发。
如果你想要使用HMAC SHA256算法,那么这个签名是这样创建的:
其实,生成的jwt就长这样,base64urlEncode(header).base64urlEncode(payload).signature,而signature如上图所示。
(引用)注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
这个Signature通常拿来验证消息在此过程中是否被更改,以及在这种情况下签发的tokens也可以用来验证JWT的发送方所表明的真实身份。
总得来说三部分输出的是三个由‘.’分割的base64url编码字符串,可以在html和HTTP华宁中简洁又轻松的传输这些字符串,相较于基于XML标准的(比如:SAML),它更简洁紧凑。
那为什么要使用JSON Web Tokens?好处!
1、因为json解析很常见,并且他们是直接映射到对象的,相反XML是没有自然的文档到对象的映射,所以与SAML想比,使用JWT更容易。
2、因为用法和使用规模,对JWT的跨平台处理更简便。
3、在安全方面,只能使用HMAC算法由共享secret对SWT进行对称签名。但是,JWT和SAML令牌可以使用X.509证书形式的公用/专用密钥对进行签名。与签署JSON的简单性相比,使用XML Digital Signature签署XML而不引入模糊的安全漏洞是非常困难的。
4、对于业务上来讲,payload可以存放非机密的业务必需声明信息
5、因为不需要在服务端存储会话信息,所以易于扩展(负载均衡等等)以及减小存储压力(这一点其实是针对所有的token认证机制而言)
其实,我把signed理解为签发,是个动作,signature理解为了签名,sign还可以理解为签署,反正看了半天大概上面的就是我理解出来觉得最通畅的意思了。
哦,对了,JWT官方还提供了一本120页之多的英文文档,可以帮助你更深入的了解JWT~