JWT 扫盲

JWT(JSON Web Token)规范允许用户在客户端和服务器之间安全地传递信息,这是目前最常用的跨域认证解决方案。

JWT 的原理是服务器在通过用户认证后,生成一个 JSON 对象返回给用户,如下:

{
  "name":"reghao",
  "expire_time":"2018-10-01 00:00:00"
}

用户在之后与服务器进行通信时,都需要发送这个 JSON 对象。服务器完全依靠这个 JSON 对象识别用户身份。

JWT 组成

一个 JWT 实际上就是一个字符串,它由三部分组成:

  • 头部(header)
  • 载荷(payload)
  • 签名(signature)

头部

JWT 的头部用于描述关于该 JWT 的最基本的信息,例如它的类型及签名所用的算法等,头部可以用一个 JSON 对象来表示:

{
  "typ":"JWT",
  "alg":"HS256"
}

经过 base64 编码后的字符串如下:

ewogICJ0eXAiOiJKV1QiLAogICJhbGciOiJIUzI1NiIKfQ==

这个字符串就是 JWT 的头部。

载荷

假设要传输的数据用 JSON 对象表示如下:

{
  "iss":"reghao JWT",
  "sub":"[email protected]",
  "aud":"www.reghao.cn",
  "iat":1536911250,
  "exp":1538323200,
  "data1":"data1",
  "data2":"data2"
}
  • JSON 对象中的前 5 个字段由 JWT 标准定义:

    iss,此 JWT 的签发者

    sub,此 JWT 面向的用户

    aud,接收此 JWT 的一方

    iat,此 JWT 的签发时间

    exp,此 JWT 的过期时间

除去前述的 5 个字段外,还有 2 个字段可使用。JWT 实际规定了 7 个官方字段供使用。

  • nbf,此 JWT 的生效时间
  • jti,此 JWT 的编号

将 JSON 对象进行 base64 编码后可得到下面的字符串:

ewogICJpc3MiOiJyZWdoYW8gSldUIiwKICAic3ViIjoicmVnaGFvQHJlZ2hhby5jbiIsCiAgImF1ZCI6Ind3dy5yZWdoYW8uY24iLAogICJpYXQiOjE1MzY5MTEyNTAsCiAgImV4cCI6MTUzODMyMzIwMCwKICAiZGF0YTEiOiJkYXRhMSIsCiAgImRhdGEyIjoiZGF0YTIiCn0=

这个字符串就是 JWT 的载荷。

将 JWT 的头部和载荷使用 . 连接在一起的字符串如下:

header.payload

header 和 payload 都经过了 base64 编码。

签名

将上述拼接的字符串使用 HS256 算法进行加密,加密的时候需要提供一个密钥(secret),假设使用 reghaojwt 作为密钥,则加密后的内容如下:

eda4b06308791cd9f6d3870d2eb84ab01bb6a3d0f73c8f74ac4c635f3fee3102

这部分即是 JWT 的签名。

将签名添加到头部和载荷拼接的字符串后面,就得到了一个完成的 JWT:

header.payload.signature

header 和 payload 经过了 base64 编码,signature 是对 header.payload 进行加密后的字符串。

签名的过程,实际上是对头部和载荷的内容进行签名。一般而言,加密算法对于不同的输入产生的输出总是不同,所以若有人对头部及载荷的内容解码后进行修改,然后再编码,那么修改后的头部和载荷的签名与之前的签名是不同的。

服务器在接收到 JWT 后,会首先对头部和载荷的内容使用同一算法(通过 JWT 的头部指定的算法)再次签名,然后与接收到的签名进行比较,若不同,则返回一个 401 Unauthorized 响应。

JWT 使用

客户端接收到服务器返回的 JWT 后,可以存储在 Cookie 中,也可存储在 localStorage。客户端在之后与服务器通信时都需要携带这个 JWT,由于放在 Cookie 中不能跨域,所以应该放在 HTTP 头部的 Authorization 字段中。

Authorization:JWT

在跨域时,也可将 JWT 放在 POST 请求的数据中。

除去认证,JWT 还可用于交换信息。有效地使用这一特性,可降低服务器查询数据的次数。

JWT 最大的缺点是无法在使用过程中废除某个 token 或更改 token 的权限,即 JWT 一旦签发,在到期之前都会始终有效。
这是由于服务器不保存 session 状态。

猜你喜欢

转载自www.cnblogs.com/reghao/p/9649081.html
jwt