今天在使用 jwt 的时候遇到一点疑问,没有想明白,来请教一下各位大佬 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhongpingjing
0D
V2EX    Java

今天在使用 jwt 的时候遇到一点疑问,没有想明白,来请教一下各位大佬

  •  
  •   zhongpingjing 2020-10-14 16:45:02 +08:00 3394 次点击
    这是一个创建于 1827 天前的主题,其中的信息可能已经有所发展或是发生改变。

    token 在签发后,校验的时候发现,payload 部分的内容如果有值,但是传参为 null 时却能校验通过

    具体案例如下

    token 解析后 payload 的内容

    { "institutionId":10, "id":1, "isAdmin":true, "exp":1603180144 } 

    institutionId 为 10,但是校验的时候,institutionId 输入 null 却能够通过,institutionId 为其他数字就不会通过。这是为什么?这是个 bug 吗?

    我想为 null 时,如果与 payload 的内容不一致时校验无法通过,应该怎么做?

    测试代码

    public static void main(String[] args) { String password = "$2a$10$G2GVQwHC1ankbyEu3nSAS.gWosqEyzg5pAzFbbxa9gLHhtgBq7DJ."; String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpbnN0aXR1dGlvbklkIjoxMCwiaWQiOjEsImlzQWRtaW4iOnRydWUsImV4cCI6MTYwMzE4MDE0NH0.9d1W50_xnfU4kT0-YWYUkPV-gM8GWa_-U6nCbuEnC84"; boolean verify1 = verify(token, password,null); System.out.println(verify1); // true 这里我期待的结果是 false,应该怎么做 boolean verify2 = verify(token, password,1L); System.out.println(verify2); // false boolean verify3 = verify(token, password,10L); System.out.println(verify3); // true } 

    检验方法

    public static boolean verify(String token,String password,Long institutionId) { try { Algorithm algorithm = Algorithm.HMAC256(password); JWTVerifier verifier = JWT.require(algorithm) .withClaim("institutionId",institutionId) .build(); verifier.verify(token); return true; } catch (Exception exception) { return false; } } 

    jwt 库

    <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.8.1</version> </dependency> 
    19 条回复    2020-10-16 10:02:57 +08:00
    qinxi
        1
    qinxi  
       2020-10-14 17:30:31 +08:00
    只校验签名, 一致则可信 ,本来就不校验具体属性的值
    zhongpingjing
        2
    zhongpingjing  
    OP
       2020-10-14 17:32:10 +08:00
    @qinxi 但是传入参数不为 null 的时候,又校验不通过
    qinxi
        3
    qinxi  
       2020-10-14 17:32:52 +08:00
    https://jwt.io/ 体验一下. 三部分数据分别修改一下看 最终的 jwt 变化规律
    qinxi
        4
    qinxi  
       2020-10-14 17:36:20 +08:00
    @zhongpingjing #2 没用过你这个 auth0 的库..不知道这个校验的是什么
    ShinChven
        5
    ShinChven  
       2020-10-14 17:37:41 +08:00
    一般要取出数据,如 id,再去数据库里面查询一次,而不是直仅用 jwt 本身校验。
    czzt1
        6
    czzt1  
       2020-10-14 17:38:40 +08:00   1
    payload 里的内容一般还是自己再去校验,而不是通过 jwt 校验,jwt 只负责签名和到期校验就可以了
    qinxi
        7
    qinxi  
       2020-10-14 17:41:16 +08:00
    查到了
    代码 com.auth0.jwt.JWTVerifier#verifyClaims 写了校验规则

    他这个校验具体内容 switch case 里面有写
    qinxi
        8
    qinxi  
       2020-10-14 17:49:12 +08:00   1
    private void requireClaim(String name, Object value) {
    if (value == null) {
    this.claims.remove(name);
    } else {
    this.claims.put(name, value);
    }
    }


    我错了...
    注意这个. value 为 null 是移除
    zhongpingjing
        9
    zhongpingjing  
    OP
       2020-10-14 18:50:51 +08:00
    @qinxi 感谢,通过 debug 发现了,为 null 时不会被校验。
    zhongpingjing
        10
    zhongpingjing  
    OP
       2020-10-14 19:07:24 +08:00
    @czzt1 感谢建议,已经发现问题了,改为手动验证了
    optional
        11
    optional  
       2020-10-14 19:16:00 +08:00
    @ShinChven 去数据库再查一次你就不应该用 jwt,db based session 适合你。
    lijialong1313
        12
    lijialong1313  
       2020-10-15 08:49:02 +08:00
    @optional 无状态怎么 session 好啊,随机生成个值然后服务器记着嘛
    tamer
        13
    tamer  
       2020-10-15 09:11:43 +08:00
    @optional jwt 本身 server 需要一个'数据源'用来做比对,数据库查询获取数据没什么问题
    liuxiaohua
        14
    liuxiaohua  
       2020-10-15 14:14:53 +08:00
    我也看到了,这个 institutionId 是设置什么,我发现我没设置
    private void requireClaim(String name, Object value) {
    if (value == null) {
    this.claims.remove(name);
    } else {
    this.claims.put(name, value);
    }
    }
    zhongpingjing
        15
    zhongpingjing  
    OP
       2020-10-15 14:44:11 +08:00
    @liuxiaohua 这是自定义 payload 的内容哈
    optional
        16
    optional  
       2020-10-15 16:01:29 +08:00 via iPhone
    @lijialong1313 再查数据库 和 db based session 有何区别?
    @tamer jwt 不需要, 用 jwt 当 session 用的才需要。
    lijialong1313
        17
    lijialong1313  
       2020-10-16 08:33:42 +08:00
    @optional 它只要不是劣于 session 就可以了。因为 session 是基于 cookies 的,都叫无状态了很少会带 cookies 。
    optional
        18
    optional  
       2020-10-16 09:01:53 +08:00 via iPhone
    @lijialong1313 本质上是一样的,你也可以用随机的 Authorization 当 session id 比 jwt 短多了。
    lijialong1313
        19
    lijialong1313  
       2020-10-16 10:02:57 +08:00
    @optional session 也不短吧,我写过一个 session 是随机生成的,然后 jwt 也用 session,然后也有签名算法和加密算法。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     958 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 19:07 PVG 03:07 LAX 12:07 JFK 15:07
    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