JSON Web Token 介绍

什么是 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令牌

JSON Web Token 介绍_第1张图片
encoded-jwt3.png

你可以使用 jwt.io Debugger进行解码以及验证

JSON Web Token 如何工作

在认证场景中,相较于传统的模式(在服务端生成会话并返回一个cookie),当用户使用他们的凭据成功登录以后,一个JSON Web Token将会被返回,该令牌必须被保存在本地(典型的场景是保存在本地存储中,不过cookie也常常用来保存这一类信息)。

无论何时,当用户想要访问一个受保护的资源,他必须将JWT发送到服务端,典型的发送方式是通过 Authorization 请求头字段,并指定 Bearer 模式。请求头的内容看起来会像下面这样:

Authorization: Bearer 

这是一个无状态的认证机制,用户信息永远也不会保存在服务器的内存中。服务器受保护的路由会检查通过Authorization头传递的令牌是否是一个正确的令牌,如果检查通过,用户将被允许访问受保护的资源。由于JWT是自包含的,所有必要的信息都包含在令牌中,进而减少了查询数据库所需要的时间。

正因为如此,JWT允许你的服务完全依赖于无状态的数据接口。它不关心你的APIs寄宿在哪个域名之下,因此跨域访问(CORS)将不会成为一个问题(使用cookie就不行)

下面的图表展示了整个处理流程


JSON Web Token 介绍_第2张图片
jwt-diagram.png

你可能感兴趣的:(JSON Web Token 介绍)