【发布时间】:2022-11-06 04:06:40
【问题描述】:
我在 REST 服务应用程序中工作并生成令牌并成功测试它。它可以工作,但是在重新运行应用程序后测试相同的令牌时,它会给我这个错误消息(JWT 签名与本地计算的签名不匹配。JWT 有效性不能被断言并且不应该被信任。--{})。 我认为每次关闭并运行应用程序时可能会更改 Java Key 中的问题并且找不到解决方案。
在这里,我使用 Postman 并生成访问令牌。
成功测试令牌。
重建项目后测试相同的令牌。
TokenUtils 类用于生成访问令牌和验证。
package com.keroles.jobify.Sec.Token.Util;
import com.keroles.jobify.Sec.Token.Model.TokenModel;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.security.Key;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Slf4j
@Getter
public class TokenUtils {
private final long ACCESS_TOKEN_VALIDITY=432000L;//7days
private final long REFRESH_TOKEN_VALIDITY=604800L;//7days
@Getter(AccessLevel.NONE)
private final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public String generateToken(Authentication authentication ,long validityTime){
log.error("{}",key.getEncoded());
log.error(key.getEncoded().toString());
return Jwts
.builder()
.setClaims(prepareClaims(authentication))
.setSubject(authentication.getName())
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis()
+ validityTime * 1000))
.signWith(key)
.compact();
}
public TokenModel getTokenModel(String token){
Claims claims= getAllClaimsFromToken(token);
return TokenModel
.builder()
.username(claims.getSubject())
.roles((List<String>)claims.get("roles"))
.createdAt(new Date( (Long) claims.get("created")))
.expirationDate(claims.getExpiration())
.build();
}
public boolean validateToken(TokenModel tokenModel, UserDetails userDetails){
return (userDetails!=null
&& tokenModel.getUsername().equals(userDetails.getUsername())
&& ! isTokenExpired(tokenModel.getExpirationDate()));
}
private boolean isTokenExpired(Date expirationDate) {
return expirationDate.before(new Date());
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
}
private Map<String,Object> prepareClaims(Authentication authentication){
List<String>authority=authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
Map<String, Object> claims = new HashMap<>();
claims.put("created",new Date());
claims.put("roles",authority);
return claims;
}
【问题讨论】:
标签: java spring-boot spring-security jwt postman