如何安全地解码 JWT 并检查其声明
快速解答
JWT 是由点连接的三个 Base64URL 字符串:header.payload.signature。使用 Base64URL 解码对标头和有效负载进行解码以检查声明,但解码仅读取数据,不会验证真实性。在信任任何声明之前,请务必验证服务器上的签名。使用我们的 JWT 解码器检查浏览器中的令牌。
介绍
JSON Web 令牌(JWT,RFC 7519)是一种紧凑的、URL 安全的令牌格式,用于身份验证和授权。它具有三个由点分隔的 Base64URL 编码部分:header.payload.signature。标头描述算法,有效负载携带声明(用户 ID、角色、到期日),签名证明令牌是由受信任方颁发的。至关重要的是,标头和有效负载是经过编码的,而不是加密的——任何人都可以读取它们。
步步
-
将令牌分为三部分
JWT 看起来像 xxxxx.yyyyy.zzzzz。按点字符拆分以获得标头(第 0 部分)、有效负载(第 1 部分)和签名(第 2 部分)。如果不完全是三个部分,则令牌格式错误。
-
Base64URL-解码标头
标头是 Base64URL 编码的 JSON 对象,例如 {"alg":"HS256","typ":"JWT"}。 Base64URL 使用 - 和 _ 代替 + 和 / 并省略填充。对其进行解码,然后 JSON.parse 读取算法和类型。我们的 JWT 解码器会自动执行此操作。
-
Base64URL 对有效负载进行解码(声明)
有效负载是声明的 JSON 对象。注册的声明包括 iss(发行者)、sub(主题)、aud(受众)、exp(到期)、nbf(不早于)、iat(发行时间)和 jti(代币 ID)。私人声明是特定于应用程序的(例如角色、电子邮件)。解码和检查,但在验证之前不要信任。
-
检查过期和未提前索赔
exp 和 nbf 是 Unix 时间戳(秒)。如果当前时间超过 exp,则令牌已过期且必须被拒绝。如果当前时间早于nbf,则令牌尚未生效。检查这些客户端的用户体验,但在服务器端强制执行它们以确保安全。
-
验证服务器上的签名(绝不是客户端)
HS256 的签名为 HMAC-SHA256(secret, header.payload),RS256/ES256 的签名为 RSA/ECDSA 签名。验证需要秘密或公钥,该密钥绝不能到达浏览器。使用 jsonwebtoken (Node) 或 jose 等库进行验证——切勿编写自己的加密货币。
示例
典型的JWT(三部分)
输入: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpmeJf36POk6yJV_adQssw5c
输出: Header: {"alg":"HS256","typ":"JWT"} Payload: {"sub":"1234567890","name":"John Doe","iat":1516239022}
使用标准声明解码有效负载
输入: 真实身份验证令牌的有效负载
输出: {"sub":"user-42","iss":"freeonlinetoolsgo.com","exp":1767229200,"iat":1767225600,"role":"admin"}
过期令牌检测
输入: 过期:1609459200 (2021-01-01) 检查于 2026-08-28
输出: Token is expired —current time (1767225600) > exp (1609459200). Reject and prompt re-login.
常见问题
- 将解码视为验证:任何人都可以使用任何声明和虚假签名制作 JWT 。解码读取有效负载,但无法证明任何内容。在信任声明之前,始终使用服务器上的秘密/公钥验证签名。
- 使用“none”算法:JWT 规范允许 alg: none 用于不安全的令牌。如果您的验证者接受 alg: none,则攻击者可以伪造令牌。配置您的库以拒绝任何预期算法并将其列入白名单。
- 在 localStorage 中存储 JWT:XSS 可以读取 localStorage 并窃取令牌。优先选择 httpOnly、Secure、SameSite=Strict cookie 作为会话令牌,或使用刷新令牌 cookie 的短期内存令牌。
- 不检查 exp/aud/iss:被盗的令牌在过期之前一直有效。始终检查每个请求的 exp(过期)、aud(目标受众)和 iss(发行者),以防止跨服务重放令牌。
提示
- 使用短期访问令牌(15 分钟)加上长期刷新令牌 — 这会限制访问令牌被盗的窗口。
- 当多个服务验证令牌时,优先选择 RS256(非对称)而不是 HS256(对称):每个服务都获取公钥,并且只有颁发者拥有私钥。
- 在开发过程中使用我们的 JWT 解码器来检查服务器正在发出的内容 - 它显示解码后的标头、有效负载和人类可读的声明摘要,而无需将令牌发送到任何地方。
- 切勿将敏感数据(密码、PII)放入 JWT 有效负载中 - 它是 Base64 编码的,未加密,任何拦截令牌的人都可以读取每个声明。