在现代 Web 开发中,身份认证是绕不开的话题。随着微服务架构和前后端分离模式的普及,传统的基于 Session-Cookie 的认证方式逐渐显露出局限性。
取而代之的是 JSON Web Token (JWT)。它轻量、无状态、跨语言,成为了目前最流行的跨域认证解决方案。
作为一名开发者,你可能已经在使用 JWT,但你真的理解它的内部原理吗?你知道如何安全地存储它吗?本文将带你从头到尾彻底解析 JWT。
为什么我们需要 JWT?
在讲'是什么'之前,先看'为什么'。
传统的 Session 认证模式
在早期的 Web 开发中,我们通常这样做:
- 用户登录,服务器验证通过。
- 服务器在内存或数据库中创建一个 Session,并记录用户信息。
- 服务器将 Session ID 返回给浏览器,写入 Cookie。
- 之后浏览器的每次请求都会自动带上这个 Cookie。
- 服务器拿着 Cookie 里的 ID 去查 Session,确认用户身份。
这种模式的问题在于:
- 扩展性差(Stateful): 服务器必须保存状态。如果你的应用做负载均衡,用户第一次请求到了服务器 A,第二次请求到了服务器 B,服务器 B 没有这个 Session,用户就掉线了(除非做复杂的 Session 同步或使用 Redis 集中存储)。
- CORS(跨域)问题: Cookie 在跨域场景下处理起来非常麻烦。
- CSRF 攻击: 基于 Cookie 的自动发送特性,容易遭受跨站请求伪造攻击。
JWT 的无状态革命
JWT 的核心思想很简单:服务器不再保存任何 Session 数据。
服务器仅负责生成一个'令牌'(Token),这个令牌里包含了用户是谁、有什么权限、什么时候过期。服务器对这个令牌进行签名(防止篡改),然后发给客户端。客户端自己保存这个令牌,每次请求带上即可。
JWT 是什么?长什么样?
根据 RFC 7519 标准,JWT 是一个紧凑的、URL 安全的字符串。它的样子通常是这样的:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
仔细观察,你会发现它由三部分组成,中间用点(.)隔开:
- Header(头部)
- Payload(负载)
- Signature(签名)
也就是:Header.Payload.Signature
第一部分:Header
Header 是一个 JSON 对象,描述了 JWT 的元数据,通常包含两部分:令牌类型(即 JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
{ "alg": "HS256", "typ": "JWT" }
最后将此 JSON 进行 Base64Url 编码,就得到了第一部分。

