什么是 JWT?一张通行证的比喻你就懂了
想象你去一家大型游乐园。以前的方式是:进门的时候办一张会员卡,游乐园的服务器记下你的信息,每次玩项目都要掏出会员卡给工作人员,他们要去后台查电脑确认你的身份。这就是传统的 Session(会话) 模式——所有信息都存在服务器上,每次请求都要查数据库。
JWT 的做法完全不一样:进门的时候,游乐园给你一张盖了防伪印章的通行证。通行证上直接写着「张三,VIP会员,有效期到今天下午6点」。你每次玩项目,工作人员看一眼通行证上的信息就知道你是谁,不需要去后台查电脑。 因为通行证上有防伪印章(数字签名),没人能伪造。
JWT(JSON Web Token,读作「乔特」)就是互联网世界里的这张通行证。 它是一个自包含的令牌,把用户信息直接编码在令牌里,服务器不需要查数据库就能知道你是谁、有什么权限。目前几乎所有的主流 Web 应用都在用 JWT:GitHub API、Google OAuth、微信开放平台、各大云厂商的鉴权系统……
| 对比项 | 传统 Session | JWT |
|---|---|---|
| 信息存储在哪 | 服务器内存/数据库 | 令牌本身 |
| 每次请求要做什么 | 查 Session 数据库 | 直接解码令牌 |
| 扩展性 | 水平扩展需要共享 Session | 天然支持分布式 |
| 是否可伪造 | 取决于 Session ID 安全 | 防伪签名保护 |
| 跨域/跨服务 | 需要额外配置 | 天然支持 |
JWT 是怎么工作的?三个部分讲清楚
一个 JWT 长成这个样子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IuW8oOS4iSIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
看上去像是一串乱码,实际上它由三个用 . 隔开的部分组成:
第一部分:Header(头部) —— 声明用什么签名算法。就像通行证上写着「本通行证使用激光防伪标记」。
第二部分:Payload(载荷) —— 存放实际数据。用户 ID、用户名、角色、过期时间……所有你想传递的信息都在这里。注意,它只是做了编码,不是加密,任何人都可以用工具解码看到里面的内容。
第三部分:Signature(签名) —— 用密钥对前两部分进行签名,防止数据被篡改。如果有人改了 Payload 里的用户名,签名就会对不上,服务器直接拒绝。
把任意一个 JWT 粘进 JWT Token 解码器,Header 和 Payload 就会以清晰的 JSON 格式显示出来——用了什么算法、Token 是谁的、什么时候过期,一目了然。
实际应用场景:JWT 就在你身边
场景一:你每天都在用的「登录状态」
你打开 Gmail、GitHub、或者公司的内部系统,输入账号密码登录。登录成功后,后端生成一个 JWT 返回给前端,前端把它存在浏览器里。之后你每次点击、每次刷新页面、每次发请求,浏览器都会自动带上这个 JWT。后端解码一看——哦,是张三,VIP 会员,没过期——放行。
这就是为什么你只需要登录一次,后面所有操作都不需要再输密码。你可以在 JWT 在线调试工具 里试一下,把任意 JWT 粘进去,看看里面到底存了哪些信息——你会发现很多网站连你的头像 URL、邮箱地址都直接写在了 Payload 里。
场景二:第三方登录(OAuth / OpenID Connect)
「使用 Google 账号登录」「使用微信登录」——你每天可能要用好几次这个功能。背后的工作机制是这样的:
- 你点击「Google 登录」,浏览器跳转到 Google 的页面
- 你输入 Google 的账号密码(这一步在 Google 的服务器上完成)
- Google 返回一个叫
id_token的东西——它就是一个 JWT - 你的网站拿着这个 JWT,解码后从 Payload 里取出你的姓名、邮箱、头像等信息
整个过程不需要你的网站去查 Google 的数据库,也不需要你把自己的密码告诉给第三方网站。一切信息都在 JWT 里自包含了。
场景三:API 接口鉴权
如果你是一个开发者,用 GitHub API 拉取仓库列表、用阿里云 API 管理服务器、用 Stripe API 处理支付——所有这些请求的鉴权几乎都在用 JWT。
你的请求 Header 里会带上这样一个东西:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
后端 API 网关收到请求后,解码这个 Bearer Token,验证签名是否有效、检查是否过期、提取用户信息——全部在毫秒级完成,不需要查数据库。对于云原生架构和微服务来说,这种无状态鉴权方式让系统可以轻松水平扩展。
场景四:前后端分离的单页应用
现在的前端项目(Vue / React / Angular)几乎都是前后端分离的。前端静态页面托管在 CDN 上,后端 API 部署在另一组服务器上。如果还用传统的 Session 方案,跨域共享 Session 需要大量的额外配置。JWT 天然解决了这个问题:前端拿着 JWT 访问不同的后端微服务,每个服务各自解码验证就好,不需要集中式的 Session 存储。
常见误区
误区一:JWT 是加密的,别人看不到内容
大错特错。JWT 的 Header 和 Payload 只是 Base64 编码,任何人都可以解码看到里面的内容。你可以把任何一个 JWT 粘进解码器,立刻就能看到里面所有的数据。所以永远不要在 JWT 里存放密码、身份证号、银行卡号等敏感信息。需要加密?额外加一层 AES 或使用 JWE(JSON Web Encryption)。
误区二:JWT 比 Session 更安全
不一定。JWT 和 Session 是不同的技术方案,各有各的安全考量。JWT 的优势是无状态和跨域便利,但如果签名密钥泄露,攻击者可以签发任意身份的 Token。Session 的安全取决于 Session ID 的随机性和传输安全性。真正决定安全性的不是用 JWT 还是 Session,而是你的实现方式——有没有用 HTTPS、密钥管理是否规范、Token 过期时间是否合理。
误区三:JWT 一旦签发就不能撤销
这是一个常见的痛点。传统 Session 模式可以随时把用户踢下线(删掉 Session 记录就行),但 JWT 只要没过期就有效。解决办法有几种:维护一个黑名单(但这样就失去了无状态的优势)、把过期时间设短(15-30分钟)、配合 Refresh Token 机制、或者用 Token 版本号方案。最优雅的做法是短寿命 Access Token + 长寿命 Refresh Token的组合方案。
误区四:JWT 越大越好,能放很多信息
JWT 的 Payload 虽然可以放任意数据,但别忘了——每次请求浏览器都会带着这个 Token 在 HTTP Header 里发送。如果 Token 太大(比如放了几十 KB 的用户信息),每次请求都会产生额外的带宽开销,影响页面加载速度。建议 Payload 里只放最核心的信息:用户 ID、角色、过期时间。其他信息需要时再通过 API 查询。
相关工具推荐
| 工具 | 用途 | 链接 |
|---|---|---|
| JWT Token 解码器 | 快速解码 JWT,查看 Header 和 Payload 内容 | 立即使用 |
| JWT 在线调试工具 | 深度调试 JWT,验证签名、分析算法、排查过期问题 | 立即使用 |
| Base64 编码解码工具 | JWT 的三部分就是 Base64 编码,配合使用验证编码问题 | 立即使用 |
| JSON 格式化工具 | 格式化解码后的 Payload,多层嵌套字段看得更清楚 | 立即使用 |
| Unix 时间戳转换器 | JWT 里的 exp/iat 字段是时间戳,一键转换为可读时间 | 立即使用 |
总结
JWT 是现代互联网架构中不可或缺的基础技术。它通过自包含的令牌设计,让分布式系统之间的身份验证变得简单高效。你每次扫码登录、每次用 API、每次在多个服务之间切换——背后都有 JWT 在默默工作。
作为普通用户,你不需要了解 JWT 的细节,但知道一件事就够了:看到带 Bearer 字样的 Token,它是一个自包含的身份证,不需要去后台确认就能验证你的身份。
作为开发者,记住三个原则:JWT 的 Payload 是透明的,别放敏感信息;签名密钥是命门,保护好它;Token 过期时间要短,配合 Refresh Token 使用。 理解这三点,你就掌握了 JWT 的精华。