Jwt是什么?

Jwt的全称是JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于将各方之间的信息安全地传输为JSON对象。 该信息可以通过数字签名进行验证和信任。 使用加密(使用HMAC算法)或使用RSA的公钥/私钥对可以对JWT进行签名。

Jwt特点:

  • 紧凑: 因为它们的尺寸较小,所以JWTs可以通过URL,POST参数,或HTTP报头内发送。此外,较小的尺寸意味着传输速度快。
  • 自包含: 负载中包含了所有用户所需要的信息,避免了需要多次查询数据库。

什么时候使用Jwt?

下面是一些Jwt的应用场景:

  • 身份认证(Authentication): 这是使用JWT最常见的场景。一旦用户登录,每个后续请求将包括JWT,让用户的接入路径,服务和资源被允许使用该令牌。单点登录是在不同的领域很容易使用的广泛使用JWT如今,由于其小的开销和它的能力的特性。
  • 信息交换: Jwt是在各方之间安全传输信息的好方法,因为它们可以被签名,例如使用公钥/私钥对,您可以确定发件人是谁。 另外,当使用标题和有效载荷计算签名时,您还可以验证内容是否未被篡改。

Jwt数据结构?

一个Jwt实际上是由以下三个部分组成:

  • header(头 部):

    • 在header中通常包含了两部分:token类型和采用的加密算法。

      1
      2
      3
      4
      {
      "alg": "HS256", //加密算法
      "typ": "JWT" //token 类型
      }
- 接下来对这部分内容使用 Base64Url 编码组成了JWT结构的第一部分。
  • payload(载荷) :

    • Token的第二部分是负载,它包含了claim, Claim是一些实体(通常指的用户)的状态和额外的元数据,有三种类型的claim: reserved , public 和 private .
    • Reserved claims: 这些claim是JWT预先定义的,在JWT中并不会强制使用它们,而是推荐使用,常用的有 iss(签发者) , exp(过期时间戳) , sub(面向的用户) , aud(接收方) , iat(签发时间) 。
    • Public claims:根据需要定义自己的字段,注意应该避免冲突。
    • Private claims:这些是自定义的字段,可以用来在双方之间交换信息。

      负载使用的例子:

      1
      2
      3
      4
      5
      {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true
      }
  • signature(签名) :

    创建签名需要使用编码后的header和payload以及一个秘钥,使用header中指定签名算法进行签名。例如如果希望使用HMAC SHA256算法,那么签名应该使用下列方式创建:

    1
    2
    3
    4
    HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)

签名用于验证消息的发送者以及消息是没有经过篡改的。

  • 完整的JWT

JWT格式的输出是以 . 分隔的三段Base64编码,与SAML等基于XML的标准相比,JWT在HTTP和HTML环境中更容易传递。

下列的JWT展示了一个完整的JWT格式,它拼接了之前的Header, Payload以及秘钥签名:

jwt

如何使用JWT?

在身份鉴定的实现中,传统方法是在服务端存储一个session,给客户端返回一个cookie,而使用JWT之后,当用户使用它的认证信息登陆系统之后,会返回给用户一个JWT,用户只需要本地保存该token(通常使用local storage,也可以使用cookie)即可。

当用户希望访问一个受保护的路由或者资源的时候,通常应该在 Authorization 头部使用 Bearer 模式添加JWT,其内容看起来是下面这样:

1
Authorization: Bearer <token>

因为用户的状态在服务端的内存中是不存储的,所以这是一种 无状态 的认证机制。服务端的保护路由将会检查请求头 Authorization 中的JWT信息,如果合法,则允许用户的行为。由于JWT是自包含的,因此减少了需要查询数据库的需要。

JWT的这些特性使得我们可以完全依赖其无状态的特性提供数据API服务,甚至是创建一个下载流服务。因为JWT并不使用Cookie的,所以你可以使用任何域名提供你的API服务而不需要担心跨域资源共享问题(CORS)。

下面的序列图展示了该过程:

jwt

为什么要使用JWT?

相比XML格式,JSON更加简洁,编码之后更小,这使得JWT比SAML更加简洁,更加适合在HTML和HTTP环境中传递。

在安全性方面,SWT只能够使用HMAC算法和共享的对称秘钥进行签名,而JWT和SAML token则可以使用X.509认证的公私秘钥对进行签名。与简单的JSON相比,XML和XML数字签名会引入复杂的安全漏洞。

因为JSON可以直接映射为对象,在大多数编程语言中都提供了JSON解析器,而XML则没有这么自然的文档-对象映射关系,这就使得使用JWT比SAML更方便。

原文: Introduction to JSON Web Tokens