How to extend java java token expiration time?

I am trying to create a Json Web Token in Java with jjwt library

But I have a problem when I try to renew.

I try it with the code below.

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(); } } 

Result:

 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

So this means that unpackage2 can not run, because it was an expiration date.

I am trying to renew.

Because I use the code in a web application.

If the user is still connecting to my application, he should not receive a token timeout.

I found another question , like mine.

+8
java token jwt
source share
1 answer

The problem is the syntax code:

 Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().setExpiration(expirationTime1).getSubject(); 

In this line, you modify the JWT that is returned by the parser. In other words, the above is equivalent to this:

 Jws<Claims> jws = Jwts.parser().setSigningKey(key).parseClaimsJws(compact); jws.getBody().setExpiration(expirationTime1).getSubject(); 

Notice how this code modifies the JWT returned by the parser? It cannot and cannot change the JWT represented by the original compact string.

The next line of code after that tries to parse the original (unmodified) compact String:

 // check if the extend expiration work. Thread.sleep(3000); System.out.println("unpackage 2 : " + Jwts.parser().setSigningKey(key).parseClaimsJws(compact).getBody().getSubject()); 

But we know that this will not work, because changing the JWT state returned by the parser does not affect the original compact line.

If your user submits the JWT to your web application, and you want to β€œextend the token's life” so that it does not expire, you must generate a new JWT and send this JWT to the user. The user should send the new JWT back to future requests. You keep repeating this process as long as you want the user to continue talking to your web application without overwriting it again.

I must point out that if you do not want to worry about this, Stormpath can perform user token and JWT authentication between the browser and your application automatically for you - you do not need to create any of them yourself (disclosure: I'm Stormpath CTO).

Finally, you might be interested to know that the JJWT test suite already checks the correct behavior in many places for both expired and premature use of tokens:

But you don’t have to come to terms with this :) Here is your code modified so that your expiration modifications function as described:

 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(); } } } 

Note that you need to create a 2nd new JWT ( compact2 ) to reflect the new / recent expiration time. You cannot modify the parsed JWT and expect the changes to be applied to the original compact value.

In conclusion, use Jwts.parser() when you need to Jwts.parser() JWT string to get a good view of Java JWT objects. Use Jwts.builder() when you need to create or modify JWT to create a new compact String view.

I hope this helps!

+9
source share

All Articles