51300520

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

  •  
  •   51300520 · Jul 6, 2019 · 10614 views
    This topic created in 2682 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

    @keepeye #9 赞同。

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

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

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

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

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

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

    没有银弹,看场合。
    51300520
    51300520
    OP
    Jul 6, 2019
    19
    这个东西好像很适合网站啊,网站一般允许多点登录
    51300520
    51300520
    OP
    Jul 6, 2019
    20
    @laoyur
    哈哈哈哈哈哈
    AlphaTr
    AlphaTr
    Jul 6, 2019 via iPhone
    21
    单点登录的话,用非对称加密,业务方用公钥验证签名就行,私钥保存在认证服务器;黑名单这种要求不严格的话,定期去认证服务器拉黑名单列表就行
    dcalsky
    dcalsky
    Jul 6, 2019 via Android
    22
    @yamedie token 放 header 里再上 ssl。如果这也能丢了那密码也能丢。主流做法是在后端存 refresh token 来刷新 access token (上文的 token )。这样能防止丢失 access token 被长期使用。
    Zzdex
    Zzdex
    Jul 6, 2019 via iPhone
    23
    .........
    limuyan44
    limuyan44
    Jul 6, 2019
    24
    https://jwt.io/introduction/ 看完对 jwt 就没那么多疑问了,jwt 本身的实现是很简陋的,如果使用 jwt 根据具体的场景更多是配合其他的策略,毕竟说白了 jwt 只是解决了数据信任的问题。
    chinvo
    chinvo
    Jul 6, 2019 via iPhone
    25
    jwt 的 payload 放一个服务器生成的字符串,验证时额外增加对 payload 的验证,“吊销”这个字符串就能达成“吊销” jwt 的目的
    loading
    loading
    Jul 6, 2019 via Android
    26
    @chinvo 既然服务器都已经要存 playload 了,不如退回去 session 方式。
    cheneydog
    cheneydog
    Jul 6, 2019
    27
    有好处也有坏处,淡定。
    yamedie
    yamedie
    Jul 6, 2019 via Android
    28
    @loading 在服务器水平扩展时需要多个服务器之间会话保持来共享 session,我个人感觉这种技术是很过时的
    loading
    loading
    Jul 6, 2019 via Android
    29
    @yamedie 所以我说没有银弹,jwt 如果安全问题需要考虑,例如要屏蔽某个 token,那么就要增加标记,然后就会遇到 session 的共享问题。
    mingmeng
    mingmeng
    Jul 7, 2019 via Android
    30
    jwt 好处是很轻,但是实际对于业务安全来说还是要做很多包装的~
    danmu17
    danmu17
    Jul 7, 2019
    31
    用 jwt 做 session token 属于安全漏洞的范畴了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1467 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 10:36 · PVG 18:36 · LAX 02:36 · JFK 05:36
    ♥ Do have faith in what you're doing.