Java生成的JWT Token验证无效问题排查
JWT Token验证无效的原因排查及修复方案
你的代码存在核心错误,导致生成的JWT在验证时失效:
问题根源
你通过Keys.secretKeyFor(SignatureAlgorithm.HS256)生成了符合HS256算法要求的SecretKey,随后将其字节数组做Base64编码得到字符串jwtTokenKey。但调用signWith(SignatureAlgorithm.HS256, jwtTokenKey)时,JJWT库会直接将该字符串转成字节数组用于签名,而非先对Base64字符串解码得到原始密钥字节。
而在验证时,若输入Base64编码后的密钥,验证端会正确解码为原始密钥字节,这就导致签名生成与验证使用的密钥不一致,最终验证失败。
修复方案
方案1:直接使用生成的SecretKey签名(推荐)
无需手动处理密钥编码,直接用生成的SecretKey调用signWith,库会自动匹配算法并正确使用密钥:
public class GeneratorJwt { public static void main(String[] args) { Map<String, Object> claims = new HashMap<>(); SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 若需要保存密钥,可先做Base64编码 String jwtTokenKey = Encoders.BASE64.encode(key.getEncoded()); String s = Jwts.builder() .setClaims(claims) .setSubject("Jack") .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date((new Date()).getTime() + 86400000)) .signWith(key) // 直接传入SecretKey .compact(); System.out.println(s); } }
方案2:使用Base64字符串密钥时需先解码
若你需要基于保存的Base64编码密钥生成签名,必须先解码为字节数组再构建SecretKey:
public class GeneratorJwt { public static void main(String[] args) { Map<String, Object> claims = new HashMap<>(); SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256); String jwtTokenKey = Encoders.BASE64.encode(key.getEncoded()); // 签名前先解码Base64字符串得到原始密钥字节 SecretKey signingKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtTokenKey)); String s = Jwts.builder() .setClaims(claims) .setSubject("Jack") .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date((new Date()).getTime() + 86400000)) .signWith(signingKey) .compact(); System.out.println(s); } }
验证注意事项
验证时输入你保存的Base64编码后的密钥字符串即可完成正确验证。
内容的提问来源于stack exchange,提问作者MarieSpeak
相关产品推荐
相关产品推荐

