JWT 身份认证的工作原理——无需会话的令牌

JWT 身份认证的工作原理,在一张交互式画布上讲清楚:凭据校验、三段式的签名令牌,以及每次请求如何无状态地完成校验。

JSON Web Token 是一份签了名、自带全部信息的身份声明:服务器在登录时生成它一次,此后每一次请求都靠这个令牌自证身份,而不必再去查会话。

JWT 身份认证的工作原理——无需会话的令牌

The interactive FlowJam canvas for this explanation — every lane, row and arrow above is a real QueryChart diagram you can open and edit.

How to read this visual

  • 从左往右读:登录、签发令牌、已认证的请求。
  • 用户这一行和服务器这一行交替出现,所以每一条箭头要么是用户在提交什么,要么是服务器在判断什么。
  • 登录列和请求列顶部的那两个拒绝方框是失败终点——画布上的每一个决策都会通向其中之一。

证明你是谁

“用户提交邮箱和密码”和“服务器对照数据库校验凭据”是整个流程中唯一出现密码的地方。“凭据有效?”把路径分成顺利的一条和“登录被拒绝”那一条。这一段是常规的身份认证——JWT 的部分要等凭据校验通过之后才开始。

铸出令牌

“服务器构建头部、载荷和签名”是这张图解的核心。头部写明签名算法;载荷承载声明——用户 id、过期时间以及任何权限范围;签名把它们绑在一起,令牌一旦被改动就会被发现。“服务器用自己的密钥为令牌签名”这一步让令牌变得可信:只有握着密钥的服务器才能产生有效的签名。“客户端收到 JWT 并保存起来”把这件成品交到客户端手里,它会一直待在那里,直到过期。

无状态校验

“客户端在 Authorization 请求头中发送 JWT”开启流程中会反复发生的那一段,而“服务器用自己的密钥校验签名”正是它能扩展的原因:重新核对一次签名是一次计算,不是一次数据库查询,所以没有中心化的会话存储需要访问。“签名有效且未过期?”再加上时间检查,把无效或过期的令牌导向“请求被拒绝,返回 401”,把有效的导向“服务器信任这些声明并处理请求”。

Key relationships and takeaways

  • 一个 JWT 由三段组成——头部、载荷、签名——用点连接;载荷可读,但改动即可被发现。
  • 签名把身份变成一项能力:持有一个有效且未过期的令牌,就是这次请求通过认证的依据。
  • 校验是无状态的——重新计算签名取代了查会话表。
  • 令牌必须由客户端妥善保存,并随每一次请求发送,因此它的过期时间才是真正的安全边界。
  • JWT 和 OAuth 是配合关系:OAuth 决定客户端可以做什么,JWT 则是承载这份授权的令牌的一种常见格式。

When to use this visual

  • 向一支新的后端团队讲清楚为什么不需要会话表,以及签名到底证明了什么。
  • 为一个横向扩展时共享状态很痛苦的服务,在 JWT 和服务端会话之间做取舍。
  • 在微服务里信任一个令牌之前,先审查它的声明——过期时间、签发者、受众。

运作方式

  1. 列出你的令牌真正携带的声明

    在“头部、载荷和签名”这一步补上你实际签发的声明——sub、exp、iss、aud 以及任何权限范围——让这张图记录下你的令牌契约。

  2. 补上刷新流程

    在过期之后插入刷新令牌的路径:客户端出示一个长期有效的刷新令牌,服务器铸出新的访问令牌,会话不必重新登录就能继续。

  3. 写明你的签名密钥策略

    在签名那一步标注你的密钥管理方式——单一共享密钥(HS256)还是一对公私钥(RS256)——因为这个选择决定了谁有能力校验令牌。

  4. 加上失败分支

    把过期的、格式错误的和被篡改的令牌都作为明确的终点画进去,让这张图覆盖你的 API 实际会返回的各种拒绝。

常见问题

JWT 是什么,里面装了什么?

JSON Web Token 是一个由三段用点分隔的字符串:一段头部,写明签名算法;一段载荷,装着关于用户和令牌有效期的声明;还有一段签名。头部和载荷是 base64 编码的 JSON——任何人都能读——而签名的作用,是让它们在没有签名密钥的情况下无法被改动。

为什么说 JWT 身份认证是无状态的?

因为服务器不保存关于会话的任何东西。每一次请求都带着令牌到来,服务器当场校验签名和过期时间。没有会话表要查,也没有状态需要在多台服务器之间复制,这正是这种做法能横向扩展的原因。代价是:不额外加一套机制的话,令牌在过期之前无法吊销。

载荷谁都能读,JWT 还安全吗?

能读和可信是两回事。载荷没有加密——不要把秘密放进去——但签名意味着任何修改都会让令牌失效,所以客户端无法擅自改写自己的声明。传输安全由 HTTPS 承担;而令牌所能访问的数据,则由资源服务器强制执行这些声明来保护。

JWT 和 OAuth 是什么关系?

它们解决的是问题的不同一半。OAuth 是授权协议——规定客户端如何获得许可和令牌。JWT 是一种令牌格式。实践中 OAuth 的访问令牌常常就是 JWT:授权服务器签发一个承载权限范围的 JWT,资源服务器负责校验。这张画布讲的是身份认证那一半,OAuth 那张图解讲的是委托那一半。

在 QueryChart(FlowJam)中编辑这张图解

把上面这张 JWT 画布原样打开成你自己的图表,把客户端和服务器改名成你自己的服务,并标注你自己的声明。

在 QueryChart(FlowJam)中编辑这张图解

可视化图解中的更多内容