关于JWT设置过期时间无效的问题

您所在的位置:网站首页 设置了数据有效性但无效 关于JWT设置过期时间无效的问题

关于JWT设置过期时间无效的问题

2024-07-15 02:17| 来源: 网络整理| 查看: 265

文章目录 一、项目场景二、问题描述三、原因分析四、解决方案

一、项目场景

项目中需要使用到 JWT 来完成用户身份信息的认证

二、问题描述

使用 JWT 时设置过期时间无效 发现如果先调用 setExpiration 方法再调用 setClaims 方法,则会出现使用 JWT 设置过期时间无效的问题

Jwts.builder() .setId(UUID.randomUUID().toString()) .setIssuedAt(new Date()) .compressWith(CompressionCodecs.GZIP) .signWith(KEY, SignatureAlgorithm.HS512) .setExpiration(new Date(currentTimeMillis + TOKEN_EXPIRATION_TIME_MILLIS)) .setClaims(claims) .compact();

而如果先调用 setClaims 方法再调用 setExpiration 方法,则不会出现该问题

Jwts.builder() .setId(UUID.randomUUID().toString()) .setIssuedAt(new Date()) .compressWith(CompressionCodecs.GZIP) .signWith(KEY, SignatureAlgorithm.HS512) .setClaims(claims) .setExpiration(new Date(currentTimeMillis + TOKEN_EXPIRATION_TIME_MILLIS)) .compact(); 三、原因分析

查看 setExpiration 方法的源码,当我们设置了过期时间时 exp != null ,这时会走到 ensureClaims().setExpiration(exp);

@Override public JwtBuilder setExpiration(Date exp) { if (exp != null) { ensureClaims().setExpiration(exp); } else { if (this.claims != null) { //noinspection ConstantConditions this.claims.setExpiration(exp); } } return this; }

然后再查看 ensureClaims 方法的源码可以发现,如果我们没有事先设置 claims ,那么在这里会产生一个 DefaultClaims 对象赋值给 DefaultJwtBuilder 类的 claims 属性,这个对象将调用 setExpiration(exp) 方法设置过期时间

protected Claims ensureClaims() { if (this.claims == null) { this.claims = new DefaultClaims(); } return this.claims; }

但如果在这之后我们再调用 setClaims 方法,那么我们新设置的 claims 将重新赋值到 DefaultJwtBuilder 类的 claims 属性

@Override public JwtBuilder setClaims(Map claims) { this.claims = new DefaultClaims(claims); return this; }

此时新构造出来的 DefaultClaims 对象没有进行设置过期时间的操作,这也就导致了最后生成的 token 没有过期时间 另一方面,setId 方法和 setIssuedAt 方法的源码跟上面 setExpiration 的源码类似,所以 setId 方法和 setIssuedAt 方法也应该在调用 setClaims 方法后再进行调用

@Override public JwtBuilder setId(String jti) { if (Strings.hasText(jti)) { ensureClaims().setId(jti); } else { if (this.claims != null) { claims.setId(jti); } } return this; } @Override public JwtBuilder setIssuedAt(Date iat) { if (iat != null) { ensureClaims().setIssuedAt(iat); } else { if (this.claims != null) { //noinspection ConstantConditions this.claims.setIssuedAt(iat); } } return this; } 四、解决方案

生成 JWT 时应该最先调用 setClaims 方法再调用其他的 setXXX 方法

Jwts.builder() .setClaims(claims) .setId(UUID.randomUUID().toString()) .setIssuedAt(new Date()) .compressWith(CompressionCodecs.GZIP) .signWith(KEY, SignatureAlgorithm.HS512) .setExpiration(new Date(currentTimeMillis + TOKEN_EXPIRATION_TIME_MILLIS)) .compact();


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3