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 1
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 1
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,然后也有签名算法和加密算法。
|