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

带吊销的 jwt 与随机生成字符串的 token 相比,有什么优势?

  •  
  •   lookas2001 · 2017-07-18 12:27:22 +08:00 · 7795 次点击
    这是一个创建于 2678 天前的主题,其中的信息可能已经有所发展或是发生改变。

    rt。
    之前看到 v2 上有一些帖子,但是这一点我没怎么弄明白。
    如果 jwt 可以吊销,那数据库(关系型或者 kv 型)中就需要存储一个 token 列表。这样的话跟随机生成的 token 在存储上的成本就一样了。
    jwt 因为要包含一系列信息,所以长度要比普通 token 长,那传输上相比于随机生成的 token 也没有优势了。
    在处理上,jwt 还需要解码,解密,校验的过程,运算成本也比随机生成的 token 高。
    如果这样看,jwt 岂不是没有优势。

    13 条回复    2017-07-19 23:38:14 +08:00
    crab
        1
    crab  
       2017-07-18 12:30:01 +08:00
    功能多。
    lookas2001
        2
    lookas2001  
    OP
       2017-07-18 12:30:51 +08:00
    @crab 比如?
    rannnn
        3
    rannnn  
       2017-07-18 12:31:41 +08:00
    jwt client 解码就知道有没有过期
    lookas2001
        4
    lookas2001  
    OP
       2017-07-18 12:33:21 +08:00
    @rannnn 但是不知道有没有效,在 jwt 可以吊销的情况下,client 不与 server 做数据交换,client 是不能知道自己的 token 还能不能用的
    mingqing
        5
    mingqing  
       2017-07-18 13:07:56 +08:00
    jwt 包含信息,且不可伪造,随机 token 无。
    mooncakejs
        6
    mooncakejs  
       2017-07-18 13:26:50 +08:00
    jwt 带有效期, revoke 列表不需要很长,只需要缓存有效期内的 revoke list 就好了
    cloud107202
        7
    cloud107202  
       2017-07-18 23:41:32 +08:00
    最近刚搞了个类似的项目,就题目中的一些用语针对说一说当梳理一下,不一定很有条理:

    1. jwt 可以吊销,至于要不要在 db 里存 token 列表可以看业务所用 token 的有效时长。很短的话(交易的分钟级,还有些数天情况的业务)用 redis 等基于内存的 cache 业足够了。以(userId, jwt, secret)这么个元祖的长度为例的话,cache 里存百万千万个数据一点都不是问题。有效期更长的话 db + cache 是一个很简单的方案。

    2. jwt 如果选用 HS256 算法,加解密是对称过程,跟非对称型加密相比开销并不大。

    3. jwt 相比随机字符串,带来的额外好处还是很明显的。签名后的 jwt 不可伪造,因为秘钥在服务端。比如在 payload 里写入你的全局 ID,这样能通过 gateway 的所有请求,到了后端各个微服务。微服务可以认为这个 token 是有效的,然后从 token 里解出 payload 确认你的真实身份,做一些额外的校验逻辑。另外 jwt 是标准格式,不但各大语言都有数个对应的实现,而且 payload 里面一些约定字段也都是标准化的,能被很多 gateway 的 plugin 所支持。比如 exp 表示过期时间,jti 避免重放攻击。还可以将一些权限 /scope 等自定义数据放到 payload 中,让 gateway 判断你这个用户被允许访问哪些 API。因为 payload 已经被 token 签名了,服务端知道 payload 有没有被篡改。

    4. 4 楼的话 我能想象出的方案是,客户端带着 token 请求 server 的任一接口,如果返回 401 token 失效 /过期 这时客户端就可以强制登出,让用户重新进行登录获取新的 token (这也算客户端能知道 token 失效的一个例子吧)
    lookas2001
        8
    lookas2001  
    OP
       2017-07-19 20:22:39 +08:00 via Android
    @cloud107202 谢谢回答~
    lookas2001
        9
    lookas2001  
    OP
       2017-07-19 20:26:13 +08:00 via Android
    @mingqing jwt 包含信息所带来的代价就是传输成本会变高(就是长),另外,随机 token 怎么伪造(汗颜)

    @mooncakejs 那如果对于一个能控制所有 token 情况下呢?服务器还是要存储所有的 token。(要不这么知道吊销哪一个)
    lookas2001
        10
    lookas2001  
    OP
       2017-07-19 20:34:44 +08:00 via Android
    @cloud107202
    1 但是不也是需要存嘛。。所以在存储代价上跟随机 token 也是一样的嘛
    3 随机 token 也不能伪造啊。在进入微服务也就是说(不知道说的对不对)在 gateway 的时候,gateway 是不是需要检测一遍 token 是否被 revoke 掉了对吧。这样的话不是还是需要去 db 或 cache (关系型或 kv 型)去查一遍,这样的话是不是就跟随机 token 的查询成本就一样了。jwt 是去 db/cache 查是否 revoke 掉了,随机 token 是去 db/cache 查是否存在顺便把数据拉回来
    jwt 的确是标准,但是其是否是必要的这就是我所想要问的。如果要设计一个完美的 token 体系,jwt 所需要的各种成本跟随机 token 我认为是不相上下的,甚至说 jwt 有加解密,编解码的过程可能还比不上随机 token
    4 这不是还是需要去与服务器通信一次嘛。。。(汗颜)
    lookas2001
        11
    lookas2001  
    OP
       2017-07-19 20:36:07 +08:00 via Android
    感谢 v2 上各位 dalao 们的意见,作为一个萌新,能获得如此多的讨论,感觉十分幸运。(果然还是 v2 能解决问题。。)
    mooncakejs
        12
    mooncakejs  
       2017-07-19 22:12:14 +08:00 via iPhone
    @lookas2001 不需要存正常的 jwt token,只要存吊销的就好。
    随机 token 的检验成本比较高,容易造成单点瓶颈。 jwt 在有效期内吊销列表并不多,查询效率高。
    lookas2001
        13
    lookas2001  
    OP
       2017-07-19 23:38:14 +08:00 via Android
    @mooncakejs 额,其实说存储正常的 token 的原因还是在于可以随时吊销不需要的 token
    不过尽管这样,如果分开存储,revoke 的单独存一份还是确实可以减少查询开支的。
    谢谢回答~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2726 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:29 · PVG 20:29 · LAX 04:29 · JFK 07:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.