如何选择身份认证模型
三种模型,之前我们都是分开来看的。把它们放在一起,各自在优化什么就清楚了——因为每一种都是拿一部分东西去换另一部分。
每种模型到底在换什么
- 有状态会话(Stateful sessions) 把一切都锚定在服务器上。身份信息在那里,控制权也在那里,所以它可预测、可更新、能瞬间撤销。作为代价,你有了一个必须持续扩容、保持同步的中心节点,而且服务器越加越多,这件事就越难。
- 不透明的持有者令牌(Opaque bearer tokens) 指向服务器。身份信息依然存放在服务器上,只不过变成了一份小小的"令牌到用户"的映射,而不是完整的会话存储。服务器因此轻了很多,但还没有完全解脱,因为查找操作依然存在。这是一种务实的折中方案。
- JWT 把"无状态"这个想法贯彻到底,把整个身份信息都塞进令牌本身。不需要查找,不需要共享存储,不需要协调,不给服务器增加负担。这是一个服务器可以立刻信任的签名对象,但一旦你需要撤销权限,麻烦就真的来了。
- 委托身份认证(Delegated identity) 把这个责任完全移出了你的系统。你不用再操心密码,但换来的是要和某个身份提供方打交道,这段关系必须处理得当,其复杂度由你来承担。
有状态是为了掌控,无状态是为了扩展,委托认证是为了把信任这件事甩出去。
Juno每种模型到底在换什么 这里面没有哪个是"最优选项"。每一种都擅长某件事,同时在别的地方付出代价。
说来也怪,这反而让人轻松了:问题不再是"哪个才是正确答案",而是"这个应用能承受在哪方面表现差一点"。
并排对比
| 有状态 | 不透明令牌 | JWT | 委托认证 | |
|---|---|---|---|---|
| 身份信息存放在哪 | 服务器上 | 服务器上,但很轻量 | 令牌里 | 提供方那里 |
| 每次请求 | 查会话 | 查令牌 | 校验签名 | 取决于之后你签发了什么 |
| 服务器存储 | 完整的会话存储 | 一份小映射 | 无 | 无 |
| 立即撤销 | 可以 | 可以 | 不行 | 部分掌握在对方手里 |
| 横向扩展 | 需要共享存储 | 需要共享存储 | 无压力 | 无压力 |
| 你放弃的东西 | 协调成本 | 部分协调成本 | 反悔的余地 | 控制权 |
Juno并排对比 "立即撤销"这一行是最该先看的。它是那种影响最大、也是后期最难改的差异。
如果你需要立刻把某个人踢出去,答案就是"某处得能查得到"。其他一切都是由此推导出来的。
各自适合什么场景
- 有状态 在服务器必须掌控全局时最合适:瞬间登出、角色权限实时生效、对用户状态的严格把控。它稳定、可预测,适合仪表盘、后台管理工具,以及任何控制权比横向扩展更重要的场景。
- 无状态 在架构需要伸展空间时最合适。对于 API,或者任何需要在没有协调式会话状态的情况下扩展的场景,让客户端自带令牌能立刻消除这种摩擦。不透明令牌保持简单;JWT 则彻底省去了查找这一步。
- 委托认证 在你意识到自己根本不想维护一套密码系统的那一刻就说得通了。或者当注册速度很重要,或者你想要一个比自己搭建更可靠的安全基线时也是如此。你的应用不再是"证明身份",而是变成"使用别人证明好的身份"。
最后值得一提的转变是:很多时候你并不需要只选一种。真实系统往往是组合使用——用委托身份认证来确认这个人是谁,用会话支撑主站点,再用 JWT 处理 API 调用。每一种都解决问题的不同侧面。
Juno各自适合什么场景 把它们组合起来听上去像是要多做很多工作,实际上通常反而更省事。每种模型只负责它擅长的那部分。
Google 负责证明你是谁,会话负责让你在网站上保持登录状态,令牌负责让你通过 API 的验证。三份活儿,三个工具。
动手试一试
五个系统。给每个系统挑一种模型,并说出决定这个选择的关键属性。
- 一个给内部员工用的经典 Web 后台。管理员需要能瞬间登出,权限变更要立刻生效,安全性比扩展性更重要。
- 一个给移动应用提供服务的公开 API。
- 一个大型微服务架构,其中十几个服务都需要知道调用方是谁。
- 一个消费者应用,目标就是让注册尽可能快,最好能用 Google 或 Apple 登录。
- 一个跑在单台服务器上的个人小项目。
对照一下你的答案
| # | 模型 | 决定性的属性 |
|---|---|---|
| 1 | 有状态 | 服务器要掌控全局。改一个角色或者把某人登出,下一次请求就要立刻生效。对于普通的浏览器应用,会话简单又可靠 |
| 2 | 无状态,两种都行 | 每个请求自带一个令牌,服务器校验完就放行,不需要随着用量增长而维护一堆越来越多的会话 |
| 3 | 无状态,具体是 JWT | 自包含,所以每个服务都能自行验证,而不用每个服务在每次调用时都去问一个中心服务器 |
| 4 | 委托认证 | 完全不用处理密码,注册速度也最快 |
| 5 | 有状态 | 能用就行,越简单越好。一台服务器,一张小小的会话表,一个 cookie。不需要令牌,不需要 OAuth,什么都不用运维 |
第 1 题和第 5 题从相反的方向得到了同一个答案,这才是有意思的地方。第 1 题选会话是因为控制权最重要;第 5 题选会话是因为别的都用不上。两者都跟"扩展性"无关——而大家往往误以为,扩展性才是决定这个选择的关键因素。
接下来去哪儿
四个问题现在会一直伴随你,遇到任何登录系统都能拿出来问:身份信息到底存在哪?服务器怎么知道这个人就是他自称的那个人?如果这份凭证泄露、过期或者被篡改了会怎样?这个应用适合哪种模型,为什么?
这是一套推理方式,而不是一份检查清单,正是它让一个陌生的身份验证系统也能被你读懂。
下一节话题完全变了。限流基础 不再关心"这个人是谁",而是开始关心"允许他们多久请求一次"。

