JSON Web Token (JWT) 是一套定义了多方之间使用 JSON 对象传输信息的标准( RFC 7519 ),适用于鉴权和交换信息。

JWT 包含 3 部分:

  1. Header:一个 JSON 对象的 Base64Url 编码格式,该 JSON 对象通常包含 token 类型和签名算法两部分。

    • 签名算法包括 HMAC,RSA,ECDSA。
    {
        "alg": "HS256",
        "typ": "JWT"
    }
    
  2. Payload:一个 JSON 对象的 Base64Url 编码格式,由若干数据的描述信息(claim)组成。

    • claim 可以分为 3 类:
      1. 标准中 预定义的 claim :如 iss (issuer),exp (expiration time),sub (subject) 等,便于互操作,推荐使用。为了保持紧凑,此类 claim 名称都是 3 个字符。
      2. 公开的 claim:可以直接从 IANA JSON Web Token Registry 中选择注册过 claim 来使用,这样可以避免随便定义新的 claim 名导致和已有的名称冲突。
      3. 隐私的 claim:JWT 的生产者和消费者之间自行约定,可能与上面两种类型的 claim 冲突。
    • 未经加密处理的 Payload 中的用户信息直接解码就能获得(因此不应该包含敏感信息),减少了数据库查询操作的次数。
    {
        "sub": "1234567890",
        "name": "John Doe"
    }
    
  3. Signature:用于校验 JWT 包含的信息是否被篡改过。

    HMACSHA256(
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        secret)
    

JWT 的 3 部分之间用 . 分隔,拼接成一个字符串。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT 在鉴权场景中的使用流程:

  1. 用户在客户端登录成功;

  2. 服务端生成 JWT 返回给客户端;

  3. 后续客户端访问受保护的路由和资源时,请求中都要带上 JWT。

    # JWT 通常放在 HTTP header 中,格式如下
    Authorization: Bearer <token>
    

JWT 的优点:

  • JSON 格式简洁易读,编码后体积小,解码操作在很多编程语言中都可以很方便地进行;

  • 支持多种签名算法;

  • 服务端无需维护 token 信息。

  • Base64:将二进制编码成文本的规则。

    • 字符集:A-Za-z0-9+/,分别对应编号 0-63(2^6)。
    • 编码:
      1. 每 3 个字节(24 bit)划成一组,不足 3 个字节则补 0 凑足 3 字节;
      2. 每 3 个字节(24 bit)分成 4 组(每组 6 bit),每组前面补上 00 凑成 1 字节,这样 24 bit 就扩展成 32 bit(4 字节,值的范围 0-63);
      3. 将每个字节映射到字符集中相应编号对应的字符。
        • 若原字符需要补一个字节的 0,则编码后的最后一个字符要覆盖为 =;若原字符需要补两个字节的 0,则编码后的最后两个字符要覆盖为 =
    • Base64URL 基于 Base64 做了一些改动(替换特殊字符,没有补位),目的是使编码的结果可以用作文件名或 URL。

References