Ujj*_*apa 4 java date utc jwt jjwt
我正在使用jjwtjwt令牌创建。使用本地系统时间设置到期日期时,一切工作正常,即
日期expDate = new Date(new Date()。getTime()+ 180000); //java.util.Date
但是我尝试使用UTC格式的日期时间,并用相同的3分钟到期日期对jwt令牌进行了签名。现在,ExpiredJwtException即使我在创建令牌后也正在进行验证,但是它正在抛出。我正在使用SimpleDateFormat将时区设置为utc。这是我在Java中使用jjwt创建令牌的代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date expDate, issDate;
try {
expDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime() + 180000));
issDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime()));
JwtBuilder builder = Jwts.builder()
.setExpiration(expDate)
.setIssuedAt(issDate)
.setId(id)
.signWith(signingKey, signatureAlgorithm);
jwtToken = builder.compact();
} catch (ParseException ex) {
}
Run Code Online (Sandbox Code Playgroud)
令牌已成功创建。我也可以在线验证内容。expDate比issDate早3分钟。我还通过传递已创建的令牌,在调用令牌后立即调用用于验证令牌的方法。我的验证方法有:
try {
Jwts.parser().setSigningKey(signingKey).parseClaimsJws(token);
log.info("jwt verification success");
} catch (ExpiredJwtException exJwt) {
log.info("expired jwt : \n{}", exJwt.getMessage());
} catch (JwtException e) {
log.info("tampered jwt");
}
Run Code Online (Sandbox Code Playgroud)
但是我越来越ExpiredJwtException。错误是
jwt已过期:JWT已于2019-05-17T01:24:48Z过期 当前时间:2019-05-17T07:06:48Z,相差20520836毫秒 允许的时钟偏移:0毫秒。
从我的日志中,此时我的令牌中的发布日期和到期日期是:
issued date is: 2019-05-17T07:06:48.000+0545
expiry date is: 2019-05-17T07:09:48.000+0545
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?并感谢您的帮助。
从Unix Epoch到1970年1月1日午夜(UTC)为止的毫秒数,SimpleDateFormat这里不需要。Date
什么可能会引起混淆,然而,这是toString()方法,因为它生成表示值的字符串时应用JVM的默认时区。
当您担心UTC时,让我只关注什么是协调世界时(UTC):这是一个时间标准(而不是时区),由高精度原子钟和地球自转共同决定。
UTC时间标准进行了数次调整,直到1972年,当时才引入leap秒以使UTC与地球自转保持一致,这并不完全均匀,也没有原子钟精确。随着地球自转速度的降低,我们不时需要在这儿插入leap秒:
虽然的内部值Date旨在反映UTC,但由于这些leap秒,它可能无法完全反映UTC。
即使Date满足您的UTC需求,也应避免使用它。现在是传统课程。
Java 8引入了一个新的API,用于基于ISO日历系统的日期,时间,瞬间和持续时间。最接近相当于Date就是Instant代表一个时间戳,在UTC时间线上的时刻。
要捕获UTC中的当前时刻,可以使用以下命令:
Instant.now(); // Capture the current moment in UTC
Run Code Online (Sandbox Code Playgroud)
您可以使用以下命令获取表示该值的字符串:
Instant.now().toString(); // 2019-05-17T12:50:40.474Z
Run Code Online (Sandbox Code Playgroud)
该字符串是根据ISO 8601格式化的,其中Z表示给定时间采用UTC。
对于JJWT,其互联互通不支持的java.time类型是,你可以创建的实例Date从Instant:
Date.from(Instant.now()); // Convert from modern class to legacy class
Run Code Online (Sandbox Code Playgroud)
这是一个测试,该测试演示了如何发行和验证令牌:
@Test
public void shouldMatchIssuedAtAndExpiration() {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
Instant issuedAt = Instant.now().truncatedTo(ChronoUnit.SECONDS);
Instant expiration = issuedAt.plus(3, ChronoUnit.MINUTES);
log.info("Issued at: {}", issuedAt);
log.info("Expires at: {}", expiration);
String jws = Jwts.builder()
.setIssuedAt(Date.from(issuedAt))
.setExpiration(Date.from(expiration))
.signWith(key)
.compact();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jws)
.getBody();
assertThat(claims.getIssuedAt().toInstant(), is(issuedAt));
assertThat(claims.getExpiration().toInstant(), is(expiration));
}
Run Code Online (Sandbox Code Playgroud)
对于上面的示例,我将JJWT 0.10.5与文档中列出的依赖项一起使用。如果需要,上面的代码是用以下import语句编写的:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.security.Key;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
999 次 |
| 最近记录: |