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>
![]() | 1 qinxi 2020-10-14 17:30:31 +08:00 只校验签名, 一致则可信 ,本来就不校验具体属性的值 |
![]() | 2 zhongpingjing OP @qinxi 但是传入参数不为 null 的时候,又校验不通过 |
![]() | 3 qinxi 2020-10-14 17:32:52 +08:00 https://jwt.io/ 体验一下. 三部分数据分别修改一下看 最终的 jwt 变化规律 |
![]() | 4 qinxi 2020-10-14 17:36:20 +08:00 @zhongpingjing #2 没用过你这个 auth0 的库..不知道这个校验的是什么 |
![]() | 5 ShinChven 2020-10-14 17:37:41 +08:00 一般要取出数据,如 id,再去数据库里面查询一次,而不是直仅用 jwt 本身校验。 |
6 czzt1 2020-10-14 17:38:40 +08:00 ![]() payload 里的内容一般还是自己再去校验,而不是通过 jwt 校验,jwt 只负责签名和到期校验就可以了 |
![]() | 7 qinxi 2020-10-14 17:41:16 +08:00 查到了 代码 com.auth0.jwt.JWTVerifier#verifyClaims 写了校验规则 他这个校验具体内容 switch case 里面有写 |
![]() | 8 qinxi 2020-10-14 17:49:12 +08:00 ![]() private void requireClaim(String name, Object value) { if (value == null) { this.claims.remove(name); } else { this.claims.put(name, value); } } 我错了... 注意这个. value 为 null 是移除 |
![]() | 9 zhongpingjing OP @qinxi 感谢,通过 debug 发现了,为 null 时不会被校验。 |
![]() | 10 zhongpingjing OP @czzt1 感谢建议,已经发现问题了,改为手动验证了 |
12 lijialong1313 2020-10-15 08:49:02 +08:00 @optional 无状态怎么 session 好啊,随机生成个值然后服务器记着嘛 |
![]() | 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); } } |
![]() | 15 zhongpingjing OP @liuxiaohua 这是自定义 payload 的内容哈 |
16 optional 2020-10-15 16:01:29 +08:00 via iPhone |
17 lijialong1313 2020-10-16 08:33:42 +08:00 @optional 它只要不是劣于 session 就可以了。因为 session 是基于 cookies 的,都叫无状态了很少会带 cookies 。 |
18 optional 2020-10-16 09:01:53 +08:00 via iPhone @lijialong1313 本质上是一样的,你也可以用随机的 Authorization 当 session id 比 jwt 短多了。 |
19 lijialong1313 2020-10-16 10:02:57 +08:00 @optional session 也不短吧,我写过一个 session 是随机生成的,然后 jwt 也用 session,然后也有签名算法和加密算法。 |