卧槽, jwt 这种认证方式竟然不需要在服务器本地存信息? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
51300520
V2EX    信息安全

卧槽, jwt 这种认证方式竟然不需要在服务器本地存信息?

  •  
  •   51300520 2019-07-06 03:43:58 +08:00 9898 次点击
    这是一个创建于 2378 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以往我登录验证一直是生成 token,发给客户端,自己存数据库,下次客户端发来我从数据库里面取出对比。

    刚调试一个 golang 的登录程序,我就纳闷,他生成一个 token 返回给客户端,我重启服务程序后该 token 竟然还能准确认证。该 token 我并没有在服务器上落地,重启后它是怎么还能继续验证的? 我以为是不是 jwt 包在哪里偷偷落地了,于是单步仔细检查了一番,发现没有。 于是 google,竟然发现这玩意不需要落地就就能一直验证。 太TM神奇了。。。。

    顺便问句,这玩意可靠吗?容易被破解不?如果可靠,那以后登录验证就用它了

    31 条回复    2019-07-07 19:47:11 +08:00
    geelaw
        1
    geelaw  
       2019-07-06 04:05:10 +08:00 via iPhone
    JWT 是数字签名,所以只需要 public key 和受信任的时间即可验证有效性
    yamedie
        2
    yamedie  
       2019-07-06 06:16:58 +08:00 via Android
    服务端不存库的话,无法解决单设备单点登录,另外还有 token 被盗用的问题。楼下讲讲如何魔改解决这俩问题?
    yamedie
        3
    yamedie  
       2019-07-06 06:21:12 +08:00 via Android
    关于 token 被盗用,忽然想到也许可以把设备的一部分特征放进 payload 里,比如 ua ?但那样会导致 token 变得巨长。。。
    yamedie
        4
    yamedie  
       2019-07-06 06:25:17 +08:00 via Android
    @yamedie 自问自答:也许可以把 ua 散列成摘要后,取几位,作为一个更短的设备特征摘要,放进 payload。缺点是加重服务端验证时的 cpu 负载
    iBenlim
        5
    iBenlim  
       2019-07-06 06:43:54 +08:00 via Android
    而且居然还可以在 Token 中存 UserId …
    mcfog
        6
    mcfog  
       2019-07-06 06:44:45 +08:00 via Android
    不建议 jwt 做一般业务的会话认证

    详情 http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
    virusdefender
        7
    virusdefender  
       2019-07-06 07:29:20 +08:00
    你会发现很多 jwt 的实现都没有改密码之后失效老 token 的功能,只能自己再包装下
    lhx2008
        8
    lhx2008  
       2019-07-06 07:45:06 +08:00 via Android   3
    简单业务,对安全没有要求可用。
    缺点不少,一个是加解密费时间,一个是 jwt 格式改了之后,后端适配很烦,一个是服务器不好做黑名单,改密码之后,jwt 仍然是有效的,必须建立一个 k-v 的黑名单,那么问题来了,已经建了这个名单,和直接存个用户 Object 有啥区别
    keepeye
        9
    keepeye  
       2019-07-06 09:22:50 +08:00
    我们正考虑不再使用 jwt,最大的原因是没法清除单个会话
    dodo2012
        10
    dodo2012  
       2019-07-06 09:24:08 +08:00
    不使用 jwt 的话,现在有啥更合适的
    hst001
        11
    hst001  
       2019-07-06 09:29:33 +08:00 via Android
    jwt 有 jwt 的问题,当时考察了一番,决定不使用,纯添麻烦。
    sparrww
        12
    sparrww  
       2019-07-06 09:42:41 +08:00
    @lhx2008 改密码的问题,生成 token 的时候把密码作为加密的一部分是可以解决的
    geelaw
        13
    geelaw  
       2019-07-06 10:02:01 +08:00 via iPhone
    @lhx2008 #8 可以给用户存一个 version number,在用户变更安全信息或者撤销所有会话的时候增加之,只有 version number 足够高的签名才有效就行了。

    @keepeye #9 赞同。

    (如果引入 state 的话 JWT 就属于传统 session 的特例了)
    laoyur
        14
    laoyur  
       2019-07-06 10:49:53 +08:00
    所以楼主的心情是:
    我擦,发现新大陆,这么好用的东东,赶紧去 v2 找认同 --> 一堆人劝退 --> 我勒个去,白高兴一场
    honeycomb
        15
    honeycomb  
       2019-07-06 10:59:55 +08:00 via Android
    @lhx2008 可以用 bloom filter 作黑名单,空间要求比 k-v 小
    MonoLogueChi
        16
    MonoLogueChi  
       2019-07-06 11:05:55 +08:00 via Android
    jwt 好像是根据密钥和时间戳验证的,只要有密钥能用,每到过期时间,就一直可以用
    loading
        17
    loading  
       2019-07-06 12:36:08 +08:00 via Android
    jwt 那串东西分三部分,前两部分都是可公开的东西,里面有 uid 什么的,最重要是有这个 token 的过期时间(这是实际时间,验证的时候是你服务器的时间,所以没有时空问题),然后这些信息 base64 了一下。

    那么如何防止别人伪造呢?

    第三段就是保证。服务器收到前两段,然后加入一个自定义的固定字符串(slat),然后用私钥加密,得到第三段。

    只要拿到这一段字符,基本就可以为所欲为,只要没超期。

    为了拦截一个已知已经被泄露的 token,jwt 里面很多时候就又会加上一个对应的 keyid,而这个 keyid 又需要在服务器进行保持,走回了老路。

    jwt 是一种轻量的登录方式,因为没魔改的话不需要跑数据,只需要加解密计算,这就不会遇到数据库瓶颈了,对不是苛刻安全要求高并发非常合适。

    没有银弹,看场合。
    jedrek
        18
    jedrek  
       2019-07-06 12:39:00 +08:00
    51300520
        19
    51300520  
    OP
       2019-07-06 13:20:47 +08:00
    这个东西好像很适合网站啊,网站一般允许多点登录
    51300520
        20
    51300520  
    OP
       2019-07-06 13:21:03 +08:00
    @laoyur
    哈哈哈哈哈哈
    AlphaTr
        21
    AlphaTr  
       2019-07-06 13:27:32 +08:00 via iPhone
    单点登录的话,用非对称加密,业务方用公钥验证签名就行,私钥保存在认证服务器;黑名单这种要求不严格的话,定期去认证服务器拉黑名单列表就行
    dcalsky
        22
    dcalsky  
       2019-07-06 14:08:05 +08:00 via Android
    @yamedie token 放 header 里再上 ssl。如果这也能丢了那密码也能丢。主流做法是在后端存 refresh token 来刷新 access token (上文的 token )。这样能防止丢失 access token 被长期使用。
    Zzdex
        23
    Zzdex  
       2019-07-06 14:08:13 +08:00 via iPhone
    .........
    limuyan44
        24
    limuyan44  
       2019-07-06 14:48:02 +08:00
    https://jwt.io/introduction/ 看完对 jwt 就没那么多疑问了,jwt 本身的实现是很简陋的,如果使用 jwt 根据具体的场景更多是配合其他的策略,毕竟说白了 jwt 只是解决了数据信任的问题。
    chinvo
        25
    chinvo  
       2019-07-06 15:59:52 +08:00 via iPhone
    jwt 的 payload 放一个服务器生成的字符串,验证时额外增加对 payload 的验证,“吊销”这个字符串就能达成“吊销” jwt 的目的
    loading
        26
    loading  
       2019-07-06 16:23:52 +08:00 via Android
    @chinvo 既然服务器都已经要存 playload 了,不如退回去 session 方式。
    cheneydog
        27
    cheneydog  
       2019-07-06 16:43:23 +08:00
    有好处也有坏处,淡定。
    yamedie
        28
    yamedie  
       2019-07-06 16:52:00 +08:00 via Android
    @loading 在服务器水平扩展时需要多个服务器之间会话保持来共享 session,我个人感觉这种技术是很过时的
    loading
        29
    loading  
       2019-07-06 17:36:45 +08:00 via Android
    @yamedie 所以我说没有银弹,jwt 如果安全问题需要考虑,例如要屏蔽某个 token,那么就要增加标记,然后就会遇到 session 的共享问题。
    mingmeng
        30
    mingmeng  
       2019-07-07 00:09:48 +08:00 via Android
    jwt 好处是很轻,但是实际对于业务安全来说还是要做很多包装的~
    danmu17
        31
    danmu17  
       2019-07-07 19:47:11 +08:00
    用 jwt 做 session token 属于安全漏洞的范畴了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     953 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 20:39 PVG 04:39 LAX 12:39 JFK 15:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86