关于国内腾讯,阿里等等互联网公司的主流业务全都不使用 jwt 做鉴权的一些思考

2021-05-10 22:40:17 +08:00
 LeeReamond

jwt 在 V2EX 也是月经水了,jwt 虽然很优雅,但所有人必须承认的一个客观事实是国内互联网企业,包括腾讯、阿里、美团等等,所使用的主流业务中无一例外没有一个使用 jwt 做鉴权的,边缘业务中即使有也很少,这个贴主要想分享一下对于这种现象的一些个人思考。

首先需要明确的是,我不是对 jwt 有意见。由于鉴权无时无刻不在发生,jwt 的设计从哲学上来讲当然是很优雅的。而且实际业务落地中也确实达到了便于横向扩展的设计目的(通过将白名单映射为黑名单的方式可以有效减轻后端压力),这点我与论坛里一些坚决认为 jwt 啥啥都不行人观点不同,我认为简单业务场景下 jwt 是达到了设计要求的,确实是一种理想方案。

我认为 jwt 尴尬的地方在于,虽然通过补丁处理后能应付简单的状态场景(比如业务场景是签发凭证后用户手机丢了,要求修改密码,屏蔽原凭证,或者用户以不高的频率要求用户组权限升级、降级,比如年费 VIP 用户组等等),但是实际业务需求中对于单个账号的状态往往远比这复杂得多,我觉得这也是国内主流互联网公司不使用 jwt 的原因。

比如典型的业务场景,一个生产业务的后端通常会对接口权限进行多维度上的拦截,比如同一个 IP 以过高频率请求同一地址是会被屏蔽的,而即使你使用多个 IP,如果账号相同,那么还是会被屏蔽,前者是对 IP 的判断,而后者是一种附加在账号上的状态判断。再比如经常有用户权限的频繁变动,比如一个账号短时间内访问频率过高,那么就被加入请稍等权限组,让用户冷静一下,过几小时再放出来,以此类推,类似这种频繁变更状态的业务使用 jwt 显然不合适。

与此同时,由于现代 nosql 的发展,比如 redis 集群远比我们想象中强大,实际生产落地中,即使是日活千万的项目(对大多数人来说这已经是规模相当大的业务了),实际换算的每秒平均请求数也仍小于 redis 集群的负载瓶颈,这也削减了 jwt 在扩展性上的优势。简单来说,虽然 jwt 帮助后端减轻压力,但其实后端并不特别 care 这部分压力,毕竟账号状态往往是 k-v 搜索,而不是复杂 sql 。结合两方面原因,这应该也是主流业务不使用 jwt 的原因。

简单总结的话,我觉得不用 jwt 不是因为 jwt 做的不好,在简单业务场景下 jwt 确实能做的比 uuid 更好,但往往业务需要维护复杂性,导致 jwt 无法胜任。而又由于,一旦有成熟方案,那么理所应当在所有业务中推广这种模式,反过来导致即使简单业务场景里也没什么人使用 jwt 解决,毕竟程序员是最贵的,性能不够可以花钱加,何必折磨自己呢?

2984 次点击
所在节点    问与答
8 条回复
abersheeran
2021-05-10 23:35:25 +08:00
确实,是你说的这样。
chinvo
2021-05-11 02:24:34 +08:00
jwt 实际上是“透明”的, 有一些信息不方便公开

而且我十分反感把 JSON 再 base64 编码这种行为…

Google 的 yaxx.balabala 的 access token 应该是用了 protobuf 编码.

测试过用 protobuf 编码, token 长度和编码解码开销直线下降

奈何没有一种标准来规范相关行为, 不方便跨语言应用.
nvkou
2021-05-11 03:02:52 +08:00
jwt 的缺陷都有解决方案。更深层的原因只是技术惰性而已,代码好好的干嘛要升级,又不是不能用。

jwt 也有不同类型的令牌对应不同场景。业务没有复杂到无法调解一说,单纯是开销问题

比起 jwt 。个人更喜欢 SAML 方案
LeeReamond
2021-05-11 04:48:32 +08:00
@nvkou 我到不觉得是技术惰性的问题,单纯是小型业务上没有升级的必要,大型业务升级了也搞不定导致的。

一个大多数人不注意的有趣讨论是,uuid 其实也能做到无状态,每个业务节点分发一份检验列表即可做到不用回源。而且实际上并不会占用多少内存,毕竟即使存百万用户的数据,现代计算机里又算得了什么呢,所以小型项目上并无升级需求,因为无论哪种方案都不够成性能瓶颈。

而大型项目上,我也不觉得 jwt 的补丁能应付需求,毕竟如果状态频繁变化的话,一个业务节点一秒钟针对同一个账号签发十个令牌,而偏偏持其中任何一个都是合法的,这对于校验逻辑来说实在是无意义的压力大。
mgcnrx11
2021-05-11 07:25:35 +08:00
还可能有一个原因,流量贵
yekern
2021-05-11 08:38:43 +08:00
还可能有一个原因,历史包袱
datoujiejie221
2021-05-11 09:00:34 +08:00
我感觉 jwt 最合适的场景是开放平台,开发平台向三方应用颁发应用颁发 jwt token,token 中的 payload 携带用户 id,应用权限等信息,这样只需要验证 token 的签名就能做好用户对个接口的访问权限。
比如 a 应用有 profile,email 的权限,而用户使用 a 应用的时候只同意了 profile 的权限,这样服务端颁发的 jwt token 的权限列表中就不包含 email,那么 a 应用就算在 token 的 payload 增加了 email 权限,但是由于签名的存在,篡改是不生效的,而且还减少了服务端通过数据库验证 token 权限的操作。
Rwing
2021-05-11 09:31:03 +08:00
有点道理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/776114

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX