php小编香蕉指出,使用JWT(JSON Web Tokens)时必须注意其有效性无法断言,不应被信任。JWT是一种用于身份验证和授权的令牌,但是由于其自包含的特性,一旦令牌被篡改,就无法确保其有效性。因此,在使用JWT时,我们应该采取严格的验证措施,包括验证签名、过期时间等,并且不要将敏感信息存储在JWT中,以免造成安全风险。
我的 jwtutil.java 代码:
@service @requiredargsconstructor public class jwtutil { private secretkey getsigningkey() { return jwts.sig.hs512.key().build(); } public string generatetoken(securitymember securitymember) { map<string, object> claims = new hashmap<>(); return createtoken(claims, securitymember.getusername()); } public string createtoken(map<string, object> claims, string subject) { return jwts.builder().claims(claims).subject(subject).issuedat(new date(system.currenttimemillis())) .expiration(new date(system.currenttimemillis() + 1000 * 60 * 60 * 10)) .signwith(getsigningkey()) .compact(); } public boolean validatetoken(string token, securitymember securitymember) { final string username = extractusername(token); return (username.equals(securitymember.getusername()) && !istokenexpired(token)); } private boolean istokenexpired(string token) { return extractexpiration(token).before(new date(system.currenttimemillis())); } public date extractexpiration(string token) { return extractclaims(token,claims::getexpiration); } public string extractusername(string token) { return extractclaims(token,claims::getsubject); } private <t> t extractclaims(string token, function<claims, t> claimsresolver) { final jwe<claims> claims = extractallclaims(token); return claimsresolver.apply(claims.getpayload()); } private jwe<claims> extractallclaims(string token) { try { return jwts.parser() .requireissuer("http://localhost:8080") .verifywith(getsigningkey()) .build() .parse(token).accept(jwe.claims); } catch (jwtexception ex) { throw new jwtexception("wrong jwt"+ex.getmessage(),ex); } } }
问题是:
Caused by: io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
您的函数 getsigningkey()
使用 jwts.sig.hs512.key().build();
,每次调用它时都会创建一个新密钥。
但是当您签署令牌和验证令牌时,您会调用 getsigningkey()
,因此在这两种情况下您都有不同的密钥。
而是创建一个密钥并存储它并使用存储的密钥。例如:
signingKey = getSigningKey(); // use it for signing Jwts.builder().signWith(signingKey)... // and verification Jwts.parser().verifyWith(signingKey)...
但是密钥的创建不应该在每次创建令牌时都发生,而应该与之分离。您还应该考虑保留密钥,以便在重新启动程序后仍然拥有相同的密钥。否则重启后所有发行的token都会失效。
验证意味着您根据用于签名的同一密钥来验证令牌签名。
以上是陷入错误。 JWT 有效性无法断言,不应被信任的详细内容。更多信息请关注PHP中文网其他相关文章!