如何延长到期时间 java json 网络令牌?
How to extend expiration time java json web token?
我尝试使用 jjwt library
在 Java 中创建 Json Web 令牌
但是我在尝试延长到期时间时遇到了问题。
我用下面的代码试试。
public class Main {
public static void main(String args[]) {
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
Date date = new Date();
long t = date.getTime();
Date expirationTime = new Date(t + 5000l); // set 5 seconds
String compact = Jwts.builder().setSubject("Joe").setExpiration(expirationTime).signWith(SignatureAlgorithm.HS256, key).compact();
System.out.println("compact : " + compact);
try {
String unpack = Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject();
System.out.println("unpackage 0 : " + unpack);
// check if the expiration work.
Thread.sleep(3000);
System.out.println("unpackage 1 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
//extend the expration time.
Date date1 = new Date();
long t1 = date1.getTime();
Date expirationTime1 = new Date(t1 + 5000l); //prolongation 5 seconds
Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject();
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
} catch (InterruptedException | ExpiredJwtException ex) {
System.out.println("exception : " + ex.getMessage());
Thread.currentThread().interrupt();
}
}
结果是:
compact : eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UiLCJleHAiOjE0Mjk2NjU1MjB9.oMY2mDHvNoMZqBfic41LbiKvAyi93wIfu_WgIADb9Wc
unpackage 0 : Joe
unpackage 1 : Joe
exception : JWT expired at 2015-04-22T08:18:40+0700. Current time: 2015-04-22T08:18:42+0700
也就是说,unpackage2不能运行,因为它已经过期了。
我想延长到期时间。
因为我在网络应用程序上应用代码。
如果用户仍然连接我的应用程序,他不应该得到令牌超时。
我发现 another question 和我的一样。
解析代码有问题:
Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject();
在这一行中,您将修改解析器返回的 JWT。换句话说,以上等同于:
Jws<Claims> jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
jws.getBody().setExpiration(expirationTime1).getSubject();
注意这段代码是如何修改解析器返回的 JWT 的吗?它不会 - 也不能 - 修改由原始 compact
String.
表示的 JWT
您之后的下一行代码尝试解析原始(未修改)compact
字符串:
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
但我们知道这是行不通的,因为更改解析器返回的 JWT 状态对原始 compact
字符串没有任何影响。
如果您的用户向您的 Web 应用程序提供 JWT,并且您想要 'extend the life' 令牌以使其不会过期,则您 必须 生成一个新的 JWT并将该 JWT 发送回用户。用户应该在以后的请求中发回新的 JWT。只要您希望允许用户继续与您的 Web 应用程序对话而无需再次重新登录,您就会一直重复此过程。
我应该指出,如果您不想担心这些事情,Stormpath 可以自动为您在浏览器和您的应用程序之间执行用户和 JWT 令牌身份验证——您不需要必须自己构建其中的任何一个(披露:我是 Stormpath 的 CTO)。
最后,您可能有兴趣知道 JJWT 的测试套件已经在许多地方验证了过期和过早令牌用例的正确行为:
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L163-L189
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L307-L335
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L421-L454
但是,您不必相信我的话:) 这是您的代码,经过修改后,您的过期修改功能将如所述:
public class Main {
public static void main(String args[]) {
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
Date date = new Date();
long t = date.getTime();
Date expirationTime = new Date(t + 5000l); // set 5 seconds
String compact = Jwts.builder().setSubject("Joe").setExpiration(expirationTime).signWith(SignatureAlgorithm.HS256, key).compact();
System.out.println("compact : " + compact);
try {
String unpack = Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject();
System.out.println("unpackage 0 : " + unpack);
// check if the expiration work.
Thread.sleep(3000);
System.out.println("unpackage 1 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
//Create a *new* token that reflects a longer extended expiration time.
Date date1 = new Date();
long t1 = date1.getTime();
Date expirationTime1 = new Date(t1 + 5000l); //prolongation 5 seconds
String compact2 = Jwts.builder().setSubject("Joe").setExpiration(expirationTime1).signWith(SignatureAlgorithm.HS256, key).compact();
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact2).getBody().getSubject());
Thread.sleep(1000);
} catch (InterruptedException | ExpiredJwtException ex) {
System.out.println("exception : " + ex.getMessage());
Thread.currentThread().interrupt();
}
}
}
请注意,需要生成第二个 new JWT (compact2
) 以反映 new/latest 过期时间。您不能修改已解析的 JWT 并期望更改应用于原始紧凑值。
总而言之,当您需要解析 JWT 字符串以获得 JWT 的良好 Java 对象表示时,请使用 Jwts.parser()
。当您需要创建或修改 JWT 以生成新的紧凑字符串表示形式时,请使用 Jwts.builder()
。
希望对您有所帮助!
我尝试使用 jjwt library
在 Java 中创建 Json Web 令牌但是我在尝试延长到期时间时遇到了问题。
我用下面的代码试试。
public class Main {
public static void main(String args[]) {
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
Date date = new Date();
long t = date.getTime();
Date expirationTime = new Date(t + 5000l); // set 5 seconds
String compact = Jwts.builder().setSubject("Joe").setExpiration(expirationTime).signWith(SignatureAlgorithm.HS256, key).compact();
System.out.println("compact : " + compact);
try {
String unpack = Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject();
System.out.println("unpackage 0 : " + unpack);
// check if the expiration work.
Thread.sleep(3000);
System.out.println("unpackage 1 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
//extend the expration time.
Date date1 = new Date();
long t1 = date1.getTime();
Date expirationTime1 = new Date(t1 + 5000l); //prolongation 5 seconds
Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject();
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
} catch (InterruptedException | ExpiredJwtException ex) {
System.out.println("exception : " + ex.getMessage());
Thread.currentThread().interrupt();
}
}
结果是:
compact : eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UiLCJleHAiOjE0Mjk2NjU1MjB9.oMY2mDHvNoMZqBfic41LbiKvAyi93wIfu_WgIADb9Wc unpackage 0 : Joe unpackage 1 : Joe exception : JWT expired at 2015-04-22T08:18:40+0700. Current time: 2015-04-22T08:18:42+0700
也就是说,unpackage2不能运行,因为它已经过期了。
我想延长到期时间。
因为我在网络应用程序上应用代码。
如果用户仍然连接我的应用程序,他不应该得到令牌超时。
我发现 another question 和我的一样。
解析代码有问题:
Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject();
在这一行中,您将修改解析器返回的 JWT。换句话说,以上等同于:
Jws<Claims> jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
jws.getBody().setExpiration(expirationTime1).getSubject();
注意这段代码是如何修改解析器返回的 JWT 的吗?它不会 - 也不能 - 修改由原始 compact
String.
您之后的下一行代码尝试解析原始(未修改)compact
字符串:
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
但我们知道这是行不通的,因为更改解析器返回的 JWT 状态对原始 compact
字符串没有任何影响。
如果您的用户向您的 Web 应用程序提供 JWT,并且您想要 'extend the life' 令牌以使其不会过期,则您 必须 生成一个新的 JWT并将该 JWT 发送回用户。用户应该在以后的请求中发回新的 JWT。只要您希望允许用户继续与您的 Web 应用程序对话而无需再次重新登录,您就会一直重复此过程。
我应该指出,如果您不想担心这些事情,Stormpath 可以自动为您在浏览器和您的应用程序之间执行用户和 JWT 令牌身份验证——您不需要必须自己构建其中的任何一个(披露:我是 Stormpath 的 CTO)。
最后,您可能有兴趣知道 JJWT 的测试套件已经在许多地方验证了过期和过早令牌用例的正确行为:
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L163-L189
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L307-L335
- https://github.com/jwtk/jjwt/blob/0.4/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy#L421-L454
但是,您不必相信我的话:) 这是您的代码,经过修改后,您的过期修改功能将如所述:
public class Main {
public static void main(String args[]) {
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
Date date = new Date();
long t = date.getTime();
Date expirationTime = new Date(t + 5000l); // set 5 seconds
String compact = Jwts.builder().setSubject("Joe").setExpiration(expirationTime).signWith(SignatureAlgorithm.HS256, key).compact();
System.out.println("compact : " + compact);
try {
String unpack = Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject();
System.out.println("unpackage 0 : " + unpack);
// check if the expiration work.
Thread.sleep(3000);
System.out.println("unpackage 1 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
//Create a *new* token that reflects a longer extended expiration time.
Date date1 = new Date();
long t1 = date1.getTime();
Date expirationTime1 = new Date(t1 + 5000l); //prolongation 5 seconds
String compact2 = Jwts.builder().setSubject("Joe").setExpiration(expirationTime1).signWith(SignatureAlgorithm.HS256, key).compact();
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact2).getBody().getSubject());
Thread.sleep(1000);
} catch (InterruptedException | ExpiredJwtException ex) {
System.out.println("exception : " + ex.getMessage());
Thread.currentThread().interrupt();
}
}
}
请注意,需要生成第二个 new JWT (compact2
) 以反映 new/latest 过期时间。您不能修改已解析的 JWT 并期望更改应用于原始紧凑值。
总而言之,当您需要解析 JWT 字符串以获得 JWT 的良好 Java 对象表示时,请使用 Jwts.parser()
。当您需要创建或修改 JWT 以生成新的紧凑字符串表示形式时,请使用 Jwts.builder()
。
希望对您有所帮助!