我在使用 JJWT 库创建 JWT 时遇到问题
i'm having trouble creating a JWT with JJWT library
我在使用 JJWT 库创建 JWT 时遇到问题:https://github.com/jwtk/jjwt
我按照说明想出了这个简单的 class:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args){
Date date = new Date();
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, 1);
Date expirationDate = cal.getTime();
String jws = Jwts.builder()
.setSubject("user")
.setId("1")
.setIssuer("me")
.setIssuedAt(new Date())
.setExpiration(expirationDate)
.setIssuedAt(date)
.signWith(key)
.compact();
System.out.println("jws: "+ jws);
decode(jws);
}
public static Jws<Claims> decode(String token){
return Jwts.parser().setSigningKey(Keys.secretKeyFor(SignatureAlgorithm.HS256)).parseClaimsJws(token);
}
}
当我 运行 它时,我得到输出:
jws: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwianRpIjoiMSIsImlzcyI6InZpY3RvciIsImlhdCI6MTU3NjEwMTAyNiwiZXhwIjoxNTc2MTA0NjI2fQ.28JIsQSc273GT_qjyXEGjyh5KTJJ3thYVGQAa4ZQzvo
例外情况:
Exception in thread "main" io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:383)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513)
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:573)
at Test.decode(Test.java:38)
at Test.main(Test.java:33)
此外,当我将我的 jwt 粘贴到该站点时:https://jwt.io/
它给了我正确的(我想)header:
{
"alg": "HS256"
}
和正确的负载:
{
"sub": "user",
"jti": "1",
"iss": "victor",
"iat": 1576100934,
"exp": 1576104534
}
但是它说签名无效。
我做错了什么?如何正确创建签名?
验证意味着根据创建令牌时使用的相同密钥(在对称算法如 HS256 的情况下)检查签名。
在您的代码中,您使用 convenience function:
Keys.secretKeyFor(SignatureAlgorithm.HS256))
正在为给定的算法创建合适的密钥。但是您不会在令牌创建方法中的任何地方保存密钥,并在检查令牌时生成一个新密钥。那必须失败。
相反,您必须保存生成的密钥并在验证调用中使用它。
此外,当您在 jwt.io 上检查您的令牌时,您需要在右栏 'Verfify Signature' 下的输入字段中提供用于创建的密钥。不知道密钥,就无法验证签名。
在任何实际使用场景中,您不会为每个令牌创建一个新密钥,而是有一个您可能已存储在服务器端的密钥。
我在使用 JJWT 库创建 JWT 时遇到问题:https://github.com/jwtk/jjwt
我按照说明想出了这个简单的 class:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args){
Date date = new Date();
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, 1);
Date expirationDate = cal.getTime();
String jws = Jwts.builder()
.setSubject("user")
.setId("1")
.setIssuer("me")
.setIssuedAt(new Date())
.setExpiration(expirationDate)
.setIssuedAt(date)
.signWith(key)
.compact();
System.out.println("jws: "+ jws);
decode(jws);
}
public static Jws<Claims> decode(String token){
return Jwts.parser().setSigningKey(Keys.secretKeyFor(SignatureAlgorithm.HS256)).parseClaimsJws(token);
}
}
当我 运行 它时,我得到输出:
jws: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwianRpIjoiMSIsImlzcyI6InZpY3RvciIsImlhdCI6MTU3NjEwMTAyNiwiZXhwIjoxNTc2MTA0NjI2fQ.28JIsQSc273GT_qjyXEGjyh5KTJJ3thYVGQAa4ZQzvo
例外情况:
Exception in thread "main" io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:383)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513)
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:573)
at Test.decode(Test.java:38)
at Test.main(Test.java:33)
此外,当我将我的 jwt 粘贴到该站点时:https://jwt.io/ 它给了我正确的(我想)header:
{
"alg": "HS256"
}
和正确的负载:
{
"sub": "user",
"jti": "1",
"iss": "victor",
"iat": 1576100934,
"exp": 1576104534
}
但是它说签名无效。
我做错了什么?如何正确创建签名?
验证意味着根据创建令牌时使用的相同密钥(在对称算法如 HS256 的情况下)检查签名。
在您的代码中,您使用 convenience function:
Keys.secretKeyFor(SignatureAlgorithm.HS256))
正在为给定的算法创建合适的密钥。但是您不会在令牌创建方法中的任何地方保存密钥,并在检查令牌时生成一个新密钥。那必须失败。
相反,您必须保存生成的密钥并在验证调用中使用它。
此外,当您在 jwt.io 上检查您的令牌时,您需要在右栏 'Verfify Signature' 下的输入字段中提供用于创建的密钥。不知道密钥,就无法验证签名。
在任何实际使用场景中,您不会为每个令牌创建一个新密钥,而是有一个您可能已存储在服务器端的密钥。