跳到页面内容
跳到互动练习
互动课堂 / 令牌验证检验台DAILY / SECURITY TERMS

044 / Web 与应用 / JWT

声明能读出来,就值得相信吗?

JWT · JWT

令牌写着一个用户和一组权限。接收它的 API 仍要追问:谁签的、发给谁、现在有效吗、准备用来做什么?最后再判断这次操作是否获准。

开始探索 ↓9–12 分钟
动手实验 · 场景判断 · 实用检查

守卫拿着人物卷轴,用发光圆镜核验;旁边兜帽人物的相似卷轴带着红叉。卷轴比喻本页的签名令牌,画里的勾不能替代签发者、受众、时间与业务权限检查。

展开读图提示
读图提示
角色与机制
卷轴比喻携带声明的令牌,守卫比喻验证令牌的服务端;这里展示的是带签名 JWT 的使用场景。
风险在哪里
读取到声明不代表已验证它;仅验签而忽略签发者、受众或有效期,也可能接受不适用的令牌。
防护与边界
固定允许的算法并验证签名及所需声明。签名不等于加密,常见 JWS 载荷可读;每次业务操作仍须授权。

JWT · 本课场景

城门守卫拿着人物卷轴,用发光圆镜验出勾号,旁边兜帽人物手中的相似卷轴则带着红叉。

守卫拿着人物卷轴,用发光圆镜核验;旁边兜帽人物的相似卷轴带着红叉。卷轴比喻本页的签名令牌,画里的勾不能替代签发者、受众、时间与业务权限检查。

读图提示
角色与机制
卷轴比喻携带声明的令牌,守卫比喻验证令牌的服务端;这里展示的是带签名 JWT 的使用场景。
风险在哪里
读取到声明不代表已验证它;仅验签而忽略签发者、受众或有效期,也可能接受不适用的令牌。
防护与边界
固定允许的算法并验证签名及所需声明。签名不等于加密,常见 JWS 载荷可读;每次业务操作仍须授权。

按 Esc 或点击画面外侧关闭。打开原图 ↗

本课任务 / JWT

把解码、令牌验证与业务授权拆开,找出固定校验链的首个失败点。

  • 理解限定的三段式签名 JWT 示例
  • 检查算法、密钥、签名及所需声明
  • 区别令牌有效与操作获准

本页讨论哪一种 JWT?

JWT 用来承载声明,可采用 JWS 签名或 MAC 保护,也可采用 JWE 加密。本页只模拟采用 RS256 的紧凑签名 JWT:受保护头、声明载荷和签名组成三段。[1][2]

为什么解码不等于验签?

本例头部和载荷的 Base64url 编码可以还原,不提供保密性。读到 sub 或 scope 只是看到了一个声明;完整验证之前,不能把这些值当作可信身份和权限。[2][3]

签名正确还缺什么?

签名只是校验链的一部分。接收者还要按应用规则确认可信签发者、受众、时间和用途;令牌通过后,当前动作仍需业务授权。[3][4]

亲手探索 / 不同条件,不同结果

先判断哪道检查失败,再决定动作能不能执行。

选择预置令牌、接收 API、服务端时钟、新旧密钥信任窗口和读取或删除动作。实验固定 RS256 与必需声明策略,显示首个失败点;它不解析用户令牌,也不执行真实验签。

令牌验收工作台

读得出声明,就能相信它吗?

读书会 API 收到一枚令牌。先查看它声称了什么,再预测在哪一步停下;改变接收方、时间或操作,观察同一枚令牌的不同结果。

只使用虚构记录,不接收真实令牌,不执行密码学或网络请求。下方是紧凑签名 JWT(JWS)的已解析字段,不是可用凭据;JWT 也可以加密或嵌套。

读者持有 notes:read;aud 数组包含两个收件方,但不含账单 API。

解码视图 · 不代表验证通过

头部自报的信息

{
  "alg": "RS256",
  "kid": "coral-2026-10",
  "typ": "at+jwt"
}

alg、kid 和 typ 也来自输入。kid 只帮助在已信任的密钥集合中查找,不是信任证明。

紧凑 JWS 的三个部分是头部、载荷、签名。Base64url 编码可逆,签名本身不会把载荷变成秘密。

载荷声称的事实

{
  "iss": "https://login.coral.example",
  "sub": "reader-17",
  "aud": [
    "notes-api",
    "profile-api"
  ],
  "iat": 1791453600,
  "nbf": 1791453600,
  "exp": 1791454200,
  "jti": "fixture-001",
  "client_id": "reading-web",
  "scope": "notes:read",
  "token_use": "access"
}

nbf / exp 使用 Unix 秒。所有夹具的时间窗口是 2026-10-08 10:00–10:10 UTC;缺失 exp 的夹具除外。

② 改变请求上下文,不替令牌放宽必要检查
过渡期只多信任 coral-2026-09;不信任令牌自行提供的新密钥。真实轮换应有明确期限。
算法 → 密钥 → 签名 → 签发方/主体 → 接收方 → 时间 → 用途 → scope 授权。这是本实验的诊断顺序;真实库可用不同顺序,但不能漏检或提前信任声明。

尚未运行。默认是只读令牌申请删除:你预计验签会失败,还是会在后面的授权检查停下?

用一次改动检验你的解释

  1. 保留 A,把删除改为读取;再换 B。载荷里写了删除权限,为何仍不能用?
  2. 保留 A 的读取请求,先换账单 API,再换回笔记 API;把时钟从到期前 1 秒移到恰好到期。
  3. 选 G 比较两个密钥轮换状态;再选 H,解释为何签名、时间、aud 都通过仍会被拒绝。

本例假设主体和记录归属已知,未检查撤销、重放、账户状态或完整业务授权;不要把“本例允许”理解为上线安全证明。

随手查 / 把理解带回实际工作

理解机制之后,检查这些细节。

实验是简化模型。真实环境需要明确业务规则、验证失败路径,并持续维护配置与证据。

01 / 实用细节

算法由接收方策略约束

配置允许算法及对应密钥类型,不能让令牌的 alg 自行改变验证方式。本例只允许 RS256/RSA,并拒绝 none 或算法混用;这不表示所有其他算法在任何应用中都不安全。[3]

02 / 实用细节

kid 只帮助定位,不创造信任

密钥来自预先信任的签发者配置。kid 不是可信证明,令牌中的任意 URL 也不该触发自动取钥;轮换期只接受明确保留的旧钥匙,移除信任后的旧令牌应失败。[3]

03 / 实用细节

签发者、主体与受众各管一件事

iss 标明签发者,sub 标明该签发者上下文中的主体,aud 约束接收者。本例要求这些声明,并把笔记 API 与账单 API 分开;同一个签发者不等于所有服务都可接受。[1][3]

04 / 实用细节

时间边界要测试到等号

在本例零时钟宽容策略下,now 小于 nbf 时拒绝,等于 nbf 可继续;now 等于或大于 exp 时拒绝。真实系统可定义小幅时钟偏差,但需明确上限,不能随意延长令牌寿命。[1]

05 / 实用细节

令牌用途不能只靠外形判断

为不同种类令牌建立互不混用的验证规则。本例检查 typ=at+jwt 和应用私有 token_use=access;后者并非所有 JWT 的标准必填项,本演示也不宣称实现完整 RFC 9068 配置。[3][4]

06 / 实用细节

通过校验之后仍要授权和撤销设计

只读 scope 可以通过令牌验证,却不允许删除。API 还需核对对象和租户权限;签名 JWT 也不会自动拥有即时撤销能力,需要按架构设计有效期、撤销状态与密钥管理。[4]

从模拟,到验证

找一个获准的环境,实际检查一次。

勾选用于本页自查,不会自动标记整课已学会。练习与清单刷新后重置。

本页已检查 0 / 5 项

实际检查清单
30 秒场景小测

订单 API 收到一个仅签名、未加密的 JWT,已验证可信签名和必需声明,其中含用户 ID。接下来哪项判断正确?

能解释原因,再标记学会。

小测结果同步错题本;“已学会”沿用原有本地学习记录。

资料与依据

  1. IETF RFC 7519 · JSON Web Token ↗

    JWT 形式、注册声明与 nbf/exp 边界;必需声明由使用场景确定

  2. IETF RFC 7515 · JSON Web Signature ↗

    紧凑 JWS 的三个编码部分及签名输入

  3. IETF RFC 8725 · JWT Best Current Practices ↗

    算法约束、可信密钥、签发者、受众与用途隔离

  4. OWASP · REST Security ↗

    API 令牌所需声明、逐接口访问控制与提前失效

本页场景、人物与数据均为教学示例。互动选择不会上传;收藏、已学会与错题沿用当前浏览器本地存储。来源正文核对日期:2026-10-08。