【问题标题】:Testing validity time of the token测试token的有效期
【发布时间】:2020-07-13 17:58:05
【问题描述】:

我想测试我的令牌的有效时间,当我编写代码并重新启动服务器时,密钥更改。出于这个原因,我的测试总是失败。我该如何解决?

这是我的 isExpired 及其辅助方法:

final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); //This key always
// change if i restart server
.
.
.
public boolean isExpired(String token) {
    Claims claims = getClaims(token);
    return claims.getExpiration().after(new Date(System.currentTimeMillis()));
}

private Claims getClaims(String token) {
    return Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
}

【问题讨论】:

  • 与问题无关,但看起来 isExpired 方法中可能存在错误。如果声明的过期时间在当前时间之后,则该方法将返回true。如果声明的过期时间是当前时间之前,正确的行为可能是返回true
  • 我没有意识到。当使用 isExpired 时,我基本上使用它的反向形式,因为这个原因我的代码工作正常,但为了可读性我应该修复它。谢谢。@dnault

标签: java spring unit-testing testing junit


【解决方案1】:

遗憾的是,您没有提供有关用于生成 Key 的库的任何信息。通过 API 我猜是this one

正如doc 中所写,您可以了解为什么每次运行测试时都会获得另一个密钥。

在底层,JJWT 使用 JCA 提供者的 KeyGenerator 为给定算法创建具有正确最小长度的安全随机密钥。

所以每次调用Keys.secretKeyFor 时生成一个新的随机Key 是库的正常行为。

除了这些一般信息之外,还有解决您问题的方法:

如果需要保存这个新的 SecretKey,可以 Base64(或 Base64URL)编码:

String secretString = Encoders.BASE64.encode(key.getEncoded());

如果您想在每次运行测试时使用相同的 Key,则应在每次测试之前反序列化相同的 Base64 字符串。
对于反序列化,您可以使用Base64Decoder 并将byte[] 传递给SecretKey.hmacShaKeyFor-方法。 您的代码应该看起来像这样。

byte[] decodedKey = Decoders.BASE64.decode("Your_Base64_key");
SecretKey key = SecretKey.hmacShaKeyFor(decodedKey);

我建议您将 Base64 编码的 Secret 存储在测试源根目录的资源文件夹中。


我还建议您将当前日期传递给您的isExpired-Method,因为否则您的测试取决于系统当前时间。 您应该尝试消除单元测试中的所有动态事物。否则它们会变脆并开始“随机”失效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    • 2010-12-26
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 2013-06-10
    相关资源
    最近更新 更多