从 JWT 的结构、签名原理、认证流程和安全注意事项出发,理解 Token 认证机制的使用场景。
JWT 是什么
JWT 是 JSON Web Token 的缩写,它是一种开放标准,定义在 RFC 7519 中。
它的作用是:用一种紧凑的字符串格式,在不同系统之间传递声明信息。
在实际项目中,JWT 最常见的使用场景是登录认证:
- 用户登录成功后,服务端签发一个
Token。 - 客户端后续请求接口时携带这个
Token。 - 服务端验证
Token的签名和有效期。 - 验证通过后,认为当前请求来自一个可信用户。
常见的 JWT 默认不是加密,而是签名。
也就是说,JWT 可以防止内容被篡改,但不能隐藏内容。任何拿到 JWT 的人,都可以解码看到其中的 Header 和 Payload。
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 | 签名算法,例如 HS256、RS256 |
typ | Token 类型,通常是 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。它的有效期通常更长,也更敏感,因此需要更严格地管理。
一般流程是:
- 用户登录成功后,服务端同时签发
Access Token和Refresh Token。 - 客户端请求业务接口时携带
Access Token。 - 如果
Access Token过期,客户端使用Refresh Token请求刷新接口。 - 服务端验证
Refresh Token,验证通过后签发新的Access Token。 - 如果
Refresh Token也过期,用户需要重新登录。