V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LeeReamond
V2EX  ›  问与答

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

  •  
  •   LeeReamond · 2021-05-10 22:40:17 +08:00 · 2959 次点击
    这是一个创建于 1278 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 解决,毕竟程序员是最贵的,性能不够可以花钱加,何必折磨自己呢?

    8 条回复    2021-05-11 09:31:03 +08:00
    abersheeran
        1
    abersheeran  
       2021-05-10 23:35:25 +08:00
    确实,是你说的这样。
    chinvo
        2
    chinvo  
       2021-05-11 02:24:34 +08:00 via iPhone   ❤️ 1
    jwt 实际上是“透明”的, 有一些信息不方便公开

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

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

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

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

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

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

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

    而大型项目上,我也不觉得 jwt 的补丁能应付需求,毕竟如果状态频繁变化的话,一个业务节点一秒钟针对同一个账号签发十个令牌,而偏偏持其中任何一个都是合法的,这对于校验逻辑来说实在是无意义的压力大。
    mgcnrx11
        5
    mgcnrx11  
       2021-05-11 07:25:35 +08:00 via iPhone
    还可能有一个原因,流量贵
    yekern
        6
    yekern  
       2021-05-11 08:38:43 +08:00   ❤️ 1
    还可能有一个原因,历史包袱
    datoujiejie221
        7
    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
        8
    Rwing  
       2021-05-11 09:31:03 +08:00
    有点道理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 19:22 · PVG 03:22 · LAX 11:22 · JFK 14:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.