【JWT学习笔记】
JWT: JSON Web Token
可以是一种跨域的登陆态解决方案,在登陆态方面,已经有session和token的解决方案,但有时候我们并不希望在服务器增加额外的内存负担来存放session或者是希望对话能持久化,这时候用session是得不偿失的。可以采用token来解决,以数据库查询的时间换取内存的存放空间。但是这另一方面也增加了数据库的IO流量,JWT则可以解决这些问题。
关于JWT的标准RFC7519,我找到了它的定义以及规范:https://tools.ietf.org/html/rfc7519
一串合格的JWT字符串由三部分组成:头部(header)、负载(payload)、签名(signature)。
其中header和payload采用对称加密方式,在通信双方看来都是透明的,而签名采用的是非对称加密,只有服务端才可以验证。
header部分一般包含两个字段:
一个是typ,表示该token的类型,这里也就是
1 2 3 |
{ "typ": "JWT" } |
另一个字段是标识签名所用的算法是什么,比如签名用的算法是HS256,则填写
1 2 3 4 |
{ "typ": "JWT", "alg": "HS256" } |
payload部分通常存放一些声明,这些声明通常包含一个用户实体信息(比如用户名或者id),也可以存放一些附加数据。声明包含三种声明,分别是:注册声明(registered),公开声明(public),私有声明(private)。
注册声明是一组非强制性的但是规范里建议使用的声明,可以在RFC7519中查看到,字段有:
- iss
- sub
- aud
- exp
- nbf
- iat
- jti
公开声明可以随便定义,但是为了避免冲突,你最好在使用前到 IANA JSON Web Token Registry 这里申请注册你的声明。
私有声明,如果你使用了没有注册的声明,那么应该算入私有声明,私有声明仅在生产者和消费者达成共识的情况下使用,并且使用时可能会发生冲突,应当谨慎使用。
payload可能的一个示例如下:
1 2 3 4 5 |
{ "sub": "1234567890", "name": "John Doe", "admin": true } |
签名部分需要一个密钥secret,密钥仅能由自己保存,切不可泄露。
首先将header用Base64Url算法进行编码,暂且定义 first = Base64Url(header)
接着把payload也用Base64Url算法进行编码,暂且定义 second = Base64Url(header)
前面header部分已经说明使用的是非对称加密方式HS256进行签名,所以生成签名的公式是:
signature = HS256( first + '.' + second + '.' + secret )
最后你得到的一串标准的JWT应该是 first.second.signature的格式,比如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImdhbyIsImlhdCI6MTUxNjIzOTAyMn0.w3jSnIWhAzFVEPOl_SsRpXMxVqj8ywYZpC8itNVgoy8
因为前面两段没有加密,所以可以直接解码得到数据,而最后的签名是非对称加密,所以签名可以在每次这串JWT传回服务器时,验证前面的数据遭到过篡改。
- 下一篇:放弃手机的第三天我在做什么
- 上一篇:放弃手机的第四天我在做什么