What is JWT and What Problem Does It Solve?

什么是 JWT 以及它解决了什么问题?

什么是 JWT?

JWT 就是 JSON Web Token🔗,一个基于 RFC 7519🔗 的标准,可用于在两个实体(如前端和后端)间进行 JSON 对象的传输。由 headerpayloadsignature 三种数据所组成,通过 . 来区隔并使用 Base64🔗 编码以便传输。

header.payload.signature

JWT.io Debugger🔗 是个不错的平台通过在线示例了解 JWT。

基本 JWT 示例

包含有关令牌类型以及用于保护其内容的加密算法的元数据。

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

payload

包含可验证的安全性声明,例如用户身份及其允许的权限。存在三种类型的声明 (Claim)。虽然 JWT 可以传输完全自定义的数据(私有声明),但还是可以通过使用「已被标准化定义的栏位」来表示某些数据意含。

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

signature

用于验证令牌是否可信任且未被篡改。通过 Base64 编码后的 header、payload 与 secret 执行 header 标示的算法生成。

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

JWT 实现方式

JWT 有许多“实现方式”,不过本文着重 JWS。

JWT 做了什么?

后端 (Server)前端 (Client)后端 (Server)前端 (Client)loop[每次 API 请求]POST /login (用户名和密码)验证用户名和密码生成 JWT返回 JWTAuthorization: Bearer <JWT>验证 JWT 有效性返回数据 or 401 错误

在生成 JWT 时,根据 signature 使用的算法会有所不同,不过最常见是使用「非对称加密」来确保客户端的数据没有被篡改,生成时会通过私钥搭配算法计算出 signature,只要 JWT 有任何数据篡改都会导致后续验证有效性不吻合,从而确保数据的完整性。

从上面案例可以发现,重点在于确保数据的「完整性」而非「机密性」,因此还是要留意 payload 的信息是完全公开的。

JWT 解决什么问题?

基于 HTTP 无状态性,通常会需要将用户信息存储在服务器中,传统的 Session-based 认证都需要通过 session id 找到对应数据,这对于「多服务器」或「无状态 API」非常不利。

用户登录后,服务器产生一组 JWT,里面包含用户 ID、权限等信息,直接给用户保存,往后请求只要附上 JWT,服务器即可解开验证,对于扩展服务器与降低服务器负载。

JWT 可能带来什么问题?

  • 只要还没过期,服务器就会持续信任创建过的 JWT,若用户登出、权限变更、账号遭盗,JWT 无法立即作废,除非额外实现黑名单机制。
  • 前端存储 JWT 仍可能遭受 XSS 或 CSRF 等攻击。

延伸阅读