Как продлить время истечения срока действия java-токена java?

Я пытаюсь создать Json Web Token в Java с jjwt library

Но у меня проблема, когда я пытаюсь продлить срок действия.

Я пробую его по приведенному ниже коду.

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 can not run, потому что это было истечение срока.

Я пытаюсь продлить срок действия.

Потому что я применяю код в веб-приложении.

Если пользователь все еще подключается к моему приложению, он не должен получать тайм-аут токена.

Я нашел еще один вопрос, как мой.

1 ответ

Проблема заключается в синтаксическом коде:

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();
</claims>

Обратите внимание, как этот код изменяет JWT, возвращаемый парсером? Он не может и не может изменить JWT, представленный исходной строкой compact.

Следующая строка кода после этого пытается проанализировать исходный (немодифицированный) compact String:

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

Но мы знаем, что это не сработает, потому что изменение состояния JWT, возвращаемого синтаксическим анализатором, не влияет на исходную строку compact.

Если ваш пользователь представляет JWT вашему веб-приложению, и вы хотите "продлить срок службы" токена, чтобы он не истекал, вы должны сгенерировать новый JWT и отправить этот JWT пользователю. Пользователь должен отправить новый JWT обратно на будущие запросы. Вы продолжаете повторять этот процесс до тех пор, пока вы хотите, чтобы пользователь продолжал разговаривать с вашим веб-приложением, не перезаписывая его снова.

Я должен указать, что если вы не хотите беспокоиться об этом, Stormpath может выполнять токен пользователя и JWT аутентификация между браузером и вашим приложением автоматически для вас - вам не нужно создавать какие-либо из них самостоятельно (раскрытие: I'm 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();
 }
}
}

Обратите внимание, что необходимо создать 2-й новый JWT (compact2), чтобы отразить новое/последнее время истечения. Вы не можете изменить анализируемый JWT и ожидать, что изменения будут применены к исходному компактному значению.

В заключение используйте Jwts.parser(), когда вам нужно проанализировать строку JWT, чтобы получить хорошее представление объектов Java JWT. Используйте Jwts.builder(), когда вам нужно создать или изменить JWT для создания нового компактного представления String.

Я надеюсь, что это поможет!

licensed under cc by-sa 3.0 with attribution.