什么是 JWT?为什么你应该使用 JWT?

更新于 2026-01-03

JWT 正在成为保护 API 的流行方式。但 JWT 到底是什么?它又是如何工作的呢?

什么是 JWT?

JWT(JSON Web Token)是一种开放标准,用于在两个参与方(通常是客户端和服务器)之间安全地传递信息。每个 JWT 都包含经过编码的 JSON 对象,其中包含一组“声明”(claims)。JWT 使用加密算法进行签名,以确保令牌签发后其内容无法被篡改。

什么是 JSON?

对于初学者开发者来说,JSON(JavaScript Object Notation)是一种基于文本的数据格式,用于在 Web 应用程序之间传输数据。它以一种对开发者和计算机都易于访问的方式存储信息。任何编程语言都可以使用 JSON 作为数据格式,并且它正迅速成为 API 的首选语法,已逐渐取代 XML。

什么是令牌(Tokens)?

既然你已经了解了 JSON 是一种文本数据格式,你可能会问:什么是令牌(tokens)?

简单来说,令牌是一串代表其他含义的数据字符串,例如身份标识。在身份验证场景中,非 JWT 类型的令牌通常是一串字符,接收方可以用它来验证发送方的身份。这里的关键区别在于:这些字符本身没有内在含义。

JWT 是如何工作的?

JWT 与其他 Web 令牌的不同之处在于它包含一组“声明”(claims)。这些声明用于在两方之间传递信息。具体包含哪些声明,取决于实际使用场景。例如,一个声明可能说明:

  • 谁签发了该令牌(iss
  • 令牌的有效期(exp
  • 客户端被授予了哪些权限

一个 JWT 由三部分组成,各部分之间用点(.)分隔,并使用 Base64 编码序列化。在最常见的紧凑序列化格式(compact serialization)中,JWT 看起来像这样:

xxxxx.yyyyy.zzzzz

解码后,你会得到以下三部分:

  1. 头部(Header)载荷(Payload) —— 两个 JSON 字符串
  2. 签名(Signature)

头部(Header)

JOSE(JSON Object Signing and Encryption)头部包含令牌类型(此处为 JWT)以及所使用的签名算法。

载荷(Payload)

载荷包含声明(claims),通常以 JSON 字符串形式呈现,为了保持 JWT 的紧凑性,一般不超过十几个字段。服务器通常使用这些信息来验证用户是否有权执行其所请求的操作。

JWT 并没有强制要求必须包含哪些声明,但某些上层标准可能会规定必需字段。例如,在 OAuth 2.0 中将 JWT 用作 Bearer 访问令牌时,必须包含 iss(签发者)、sub(主题)、aud(受众)和 exp(过期时间)等声明。其中一些声明比其他更常见。

签名(Signature)

签名用于确保令牌未被篡抗。签发方使用一个只有签发方和接收方知道的密钥(secret),或仅签发方持有的私钥,对头部和载荷进行签名。当令牌被使用时,接收方会验证签名是否与头部和载荷匹配,从而确认 JWT 的有效性。


JWT 示例:OAuth Bearer 令牌

JWT 的一种常见用法是作为 OAuth Bearer 令牌。在此场景中:

  • 授权服务器应客户端请求生成一个 JWT,并对其进行签名,防止其他方篡改。
  • 客户端在向 REST API 发起请求时附带此 JWT。
  • REST API 验证 JWT 的签名是否与其头部和载荷一致,以判断令牌是否有效。
  • 验证通过后,API 可根据 JWT 中的声明决定是否允许客户端的请求。

用一个简单的比喻来说:
你可以把 JWT Bearer 令牌想象成进入一栋安全大楼的身份徽章。这个徽章带有特定权限(即声明),可能只允许进入大楼的某些区域。在这个类比中:

  • 授权服务器 就像前台接待处——徽章的签发者;
  • 公司 Logo 印在徽章上,类似于 JWT 的签名,用于验证真伪;
  • 如果持徽章者试图进入受限区域,系统会根据徽章上的权限(即 JWT 中的声明)决定是否放行。

为什么要使用 JWT?

简而言之,JWT 提供了一种安全认证用户并共享信息的方式。

通常,签发方使用一个私钥或共享密钥对 JWT 进行签名。接收方通过验证签名,确保令牌自签发以来未被篡改。由于签名密钥难以被未授权方猜测,因此很难伪造或修改 JWT 中的声明。

不过,并非所有签名算法都同样安全。例如:

  • 有些算法使用共享密钥(对称加密),即签发方和验证方都知道同一个密钥;
  • 另一些算法使用公钥/私钥对(非对称加密):私钥仅由签发方持有,公钥可公开分发。任何人都可用公钥验证签名,但只有私钥能生成签名。

后者更为安全,因为私钥只需存在于一处。

正因为如此,服务器无需维护一个用于识别用户的信息数据库。这对开发者来说是个好消息——签发 JWT 的服务器和验证 JWT 的服务器可以不是同一台