我尝试使用jjwt库在Java中创建Json Web Token
但是当我尝试延长到期时间时,我遇到了问题.
我通过下面的代码尝试.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
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无法运行,因为它已到期.
我试图延长到期时间.
因为我在Web应用程序上应用代码.
如果用户仍然与我的应用程序连接,他不应该获得令牌超时.
Les*_*ood 11
问题在于解析代码:
Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject();
Run Code Online (Sandbox Code Playgroud)
在这一行中,您将修改解析器返回的JWT.换句话说,以上相当于:
Jws<Claims> jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
jws.getBody().setExpiration(expirationTime1).getSubject();
Run Code Online (Sandbox Code Playgroud)
注意这段代码如何修改解析器返回的JWT?它不 - 也不能 - 修改原始compactString 表示的JWT .
之后的下一行代码尝试解析原始(未修改的)compact字符串:
// check if the extend expiration work.
Thread.sleep(3000);
System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject());
Run Code Online (Sandbox Code Playgroud)
但我们知道这不起作用,因为更改解析器返回的JWT的状态对原始compactString 没有任何影响.
如果您的用户向您的Web应用程序提供JWT并且您希望"延长令牌的生命周期"以使其不会过期,则必须生成新的JWT并将该JWT发送回用户.用户应该在将来的请求中重新发送新的JWT.只要您希望允许用户继续与您的Web应用程序通信而不必再次重新登录,您就会不断重复此过程.
我应该指出,如果您不想担心任何这些问题,Stormpath可以自动为您执行浏览器和您的应用程序之间的用户和JWT令牌身份验证 - 您不必自己构建任何此类身份验证(披露) :我是Stormpath的CTO).
最后,您可能有兴趣知道JJWT的测试套件已经在过期和过早令牌用例的许多地方验证了正确的行为:
但是,你不必接受我的话:)这是你的代码,修改后你的到期修改功能如下所述:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,需要生成第二个新的 JWT(compact2)以反映新的/最新的到期时间.您无法修改已解析的JWT并期望更改应用于原始紧凑值.
总之,Jwts.parser()在需要解析JWT字符串以获得JWT的漂亮Java对象表示时使用.使用Jwts.builder()时您需要创建或修改JWT产生一个新的紧凑型字符串表示.
我希望有所帮助!