什么是 JSON Web Token
JSON Web Token (JWT) 是为了在网络间安全地传输信息而设计的一种协议 (RFC 7519),它以JSON对象的形式存在,并且自包含。这些信息可被验证,并添加了数字签名以防止篡改。JWT可以基于HMAC哈希算法进行签名,或者使用基于公/私钥对的RSA算法进行签名。
首先,让我们更进一步得解释一下定义中的一些概念:
- 协议:JWT令牌的尺寸非常小,因此能够通过URL,POST请求体,或者直接附加到HTTP请求头中。另外,尺寸小意味着传输速度会非常快
- 自包含:JWT的载荷包含了所有需要的用户信息,避免了对数据库的多次查询
什么时候需要使用 JSON Web Token
以下是一些JSON Web Token的常用场景:
- 认证:这是JWT最常用的场景。一旦用户登录以后,之后的每一个请求将会包含JWT令牌,并允许用户访问被保护的路由,服务和资源。由于其较小的开销并能够方便得跨域使用,单点登录系统目前已广泛使用JWT。
- 信息交换:由于JSON Web Token能够被签名,因此是一种安全地交换信息的好方法。例如,使用公私钥对进行签名,你能够确保消息的发送方不是恶意伪造的,另外,由于签名是通过载荷和头部计算出来的,因此你能够确保消息内容没有被篡改过。
JSON Web Token的数据结构
JSON Web Token由三部分组成,并通过英文句号(.)隔开:
- 头部
- 载荷
- 签名
因此,一个典型的JWT令牌看起来会像这样:
xxxxx.yyyyy.zzzzz
头部
典型的头部信息包含两部分:令牌的类型 (JWT),以及签名所使用的哈希算法,例如 HMAC, SHA256, RSA
{
"alg": "HS256",
"typ": "JWT"
}
然后,这段JSON对象将使用Base64编码成字符串并放入JWT令牌的第一部分
载荷
令牌的第二部分被称为载荷,载荷中包含了声明。声明是一些实体描述(例如用户)以及相关的元数据。有三种类型的声明:reserved, public和private
- Reserved 声明:这一类预定义的声明并不是强制性的,但是推荐使用。包括:iss(发布者),exp(过期时间),sub(主题),aud(受众)等等
- Public 声明:公共声明可以添加任何信息。不过为了避免冲突,用户定义时应遵守IANA JSON Web Token Registry规范,或者包含一个防止名称冲突的命名空间,比如URI
- Private 声明:这部分声明由信息交换的双方自行定义
一个载荷的例子如下:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后使用Base64对其进行编码,得到JWT的第二部分。
签名
为了创建签名,你需要拿到编码后的头部,编码后的载荷,以及一个密钥,签名的算法在头部中进行指定。
例如,你想要使用 HMAC SHA256 算法进行签名,那么签名函数看起来将会是如下的格式:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
签名用来验证令牌的发送者不是伪造的,并确保信息不被篡改
把所有部分放在一起
最终的令牌由三部分 Base64 字符串拼接而成,中间使用英文句点(.)隔开,因此令牌可以轻松得在 HTML 和 HTTP 环境中进行传递
以下展示了之前的各个部分组合之后的完整JWT令牌
encoded-jwt3.png你可以使用jwt.io Debugger进行解码以及验证
JSON Web Token 如何工作
在认证场景中,相较于传统的模式(在服务端生成会话并返回一个cookie),当用户使用他们的凭据成功登录以后,一个JSON Web Token将会被返回,该令牌必须被保存在本地(典型的场景是保存在本地存储中,不过cookie也常常用来保存这一类信息)。
无论何时,当用户想要访问一个受保护的资源,他必须将JWT发送到服务端,典型的发送方式是通过 Authorization 请求头字段,并指定 Bearer 模式。请求头的内容看起来会像下面这样:
Authorization: Bearer <token>
这是一个无状态的认证机制,用户信息永远也不会保存在服务器的内存中。服务器受保护的路由会检查通过Authorization头传递的令牌是否是一个正确的令牌,如果检查通过,用户将被允许访问受保护的资源。由于JWT是自包含的,所有必要的信息都包含在令牌中,进而减少了查询数据库所需要的时间。
正因为如此,JWT允许你的服务完全依赖于无状态的数据接口。它不关心你的APIs寄宿在哪个域名之下,因此跨域访问(CORS)将不会成为一个问题(使用cookie就不行)
下面的图表展示了整个处理流程
jwt-diagram.png
网友评论