JWT(json web token)中的ExpiredJwtException

1. 问题重现

原本是调用jwtUtil(jwt的工具类),传入一个token,判断是否过期,然而却莫名其妙得抛异常了,而业务中还需要根据是否过期进行后续逻辑!
异常如下:

io.jsonwebtoken.ExpiredJwtException: JWT expired at 2020-07-29T14:48:14Z. Current time: 2020-07-29T14:48:50Z, a difference of 36843 milliseconds.  Allowed clock skew: 0 milliseconds.
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:385)
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
	at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541)
	at com.smart.util.JwtUtil.parseJwt(JwtUtil.java:63)
	at com.smart.util.JwtUtil.isTokenExpired(JwtUtil.java:93)

2. 问题追踪

根据报错堆栈信息找到了DefaultJwtParser类中,找到了问题的原因

                boolean allowSkew = this.allowedClockSkewMillis > 0L;
                if (claims != null) {
                    Date now = this.clock.now();
                    long nowTime = now.getTime();
                    Date exp = claims.getExpiration();
                    String nbfVal;
                    SimpleDateFormat sdf;
                    if (exp != null) {
                        long maxTime = nowTime - this.allowedClockSkewMillis;
                        Date max = allowSkew ? new Date(maxTime) : now;
                        if (max.after(exp)) {
                            sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                            String expVal = sdf.format(exp);
                            nbfVal = sdf.format(now);
                            long differenceMillis = maxTime - exp.getTime();
                            String msg = "JWT expired at " + expVal + ". Current time: " + nbfVal + ", a difference of " + differenceMillis + " milliseconds.  Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds.";
                            throw new ExpiredJwtException((Header)header, claims, msg);
                        }
                    }

看到结尾的throw new ExpiredJwtException,我相信就找到了问题的关键,原来在在解析token并发现这个token已经过期了,它作出的反应是直接抛异常,除了msg信息,还有claims和header信息;
回到我们的工具类中的解析jwt的方法:

    public Claims parseJwt(String token){
        Claims claims = Jwts.parser()
                    .setSigningKey(signKey) // 设置标识名
                    .parseClaimsJws(token)  //解析token
                    .getBody();
        return claims;
    }

改为:

	//不管是否过期,都返回claims对象
    public Claims parseJwt(String token){
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(signKey) // 设置标识名
                    .parseClaimsJws(token)  //解析token
                    .getBody();
        } catch (ExpiredJwtException e) {
            claims = e.getClaims();
        }
        return claims;
    }

可以从异常中找到这个过期的claim对象信息;
判断token是否过期的方法我也相应修改了,如下:

    public Boolean isTokenExpired(String token) {
    	//不管是否过期,都返回claims对象
        Claims claims = this.parseJwt(token);
        Date expiration = claims.getExpiration();
        //和当前时间进行对比来判断是否过期
        return new Date(System.currentTimeMillis()).after(expiration);
    }

3. 总结

多多看看错误的堆栈信息,十分有利于我们发现和解决问题!

最后,如果看完对你有所帮助,不要吝啬关注 / 点赞 / 收藏哟,感谢感谢~

  • 27
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值