从 JWT 的结构、签名原理、认证流程和安全注意事项出发,理解 Token 认证机制的使用场景。

2023-03-02 11:12:31

JWT 是什么

JWTJSON Web Token 的缩写,它是一种开放标准,定义在 RFC 7519 中。

它的作用是:用一种紧凑的字符串格式,在不同系统之间传递声明信息。

在实际项目中,JWT 最常见的使用场景是登录认证:

  • 用户登录成功后,服务端签发一个 Token
  • 客户端后续请求接口时携带这个 Token
  • 服务端验证 Token 的签名和有效期。
  • 验证通过后,认为当前请求来自一个可信用户。

常见的 JWT 默认不是加密,而是签名。

也就是说,JWT 可以防止内容被篡改,但不能隐藏内容。任何拿到 JWT 的人,都可以解码看到其中的 HeaderPayload

1. JWT 的结构

一个 JWT 由三部分组成,中间使用点号 . 分隔:

Header.Payload.Signature

三部分的作用:

部分作用
Header描述 Token 类型和签名算法
Payload存放声明信息
Signature对前两部分进行签名,防止内容被篡改

一个完整的 JWT 看起来大概是这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDAxIiwibmFtZSI6IkphY2siLCJpYXQiOjE3MDAwMDAwMDB9.xxxxx

它看起来像一串随机字符串,但前两部分只是经过 Base64URL 编码,并不是加密。

2. Header

Header 是一个 JSON 对象,用来描述这个 JWT 的基本信息。

常见内容如下:

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

字段含义:

字段说明
alg签名算法,例如 HS256RS256
typToken 类型,通常是 JWT

alg 只表示这个 JWT 声明自己使用了什么算法。服务端验证时不能盲目信任客户端传来的 alg,而应该在服务端明确限制允许的算法。

3. Payload

Payload 也是一个 JSON 对象,用来存放声明信息。

声明信息也叫 Claims。它可以表示用户是谁、什么时候签发、什么时候过期、签发方是谁、这个 Token 给谁使用等信息。

示例:

{
  "sub": "1001",
  "name": "Jack",
  "role": "admin",
  "iat": 1700000000,
  "exp": 1700003600
}

不要在 Payload 中存放敏感信息。

例如下面这些内容都不适合放进 JWT

  • 密码。
  • 手机号。
  • 身份证号。
  • 银行卡信息。
  • 访问密钥。
  • 过于详细的权限数据。

因为 Payload 只是编码,不是加密。任何拿到 JWT 的人都可以解码看到它。

4. Signature

Signature 是签名部分,用来验证 JWT 是否被篡改。

HS256 为例,签名大致可以这样理解:

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

服务端会用同样的算法和密钥重新计算签名,然后和 JWT 中携带的 Signature 进行比较。

如果两者一致,说明:

  • Header 没有被改过。
  • Payload 没有被改过。
  • 签名来自持有密钥的一方。

如果有人修改了 Payload 中的用户 ID 或角色字段,即使只改一个字符,重新计算出来的签名也会不一致,验证就会失败。

这就是 JWT 能够防篡改的原因。

5. Access Token 和 Refresh Token

项目中,常见的做法是拆成两个 Token:

Token作用有效期
Access Token访问业务接口较短
Refresh Token换取新的访问令牌较长

Access Token 用于访问业务接口,例如获取用户信息、提交订单、修改资料等。它应该设置较短的有效期,降低泄露后的风险。

Refresh Token 用于在 Access Token 过期后换取新的 Access Token。它的有效期通常更长,也更敏感,因此需要更严格地管理。

一般流程是:

  1. 用户登录成功后,服务端同时签发 Access TokenRefresh Token
  2. 客户端请求业务接口时携带 Access Token
  3. 如果 Access Token 过期,客户端使用 Refresh Token 请求刷新接口。
  4. 服务端验证 Refresh Token,验证通过后签发新的 Access Token
  5. 如果 Refresh Token 也过期,用户需要重新登录。