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);
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!