предисловие
Передняя и задняя части проекта разделены, и для проверки подлинности запроса используется проверка подлинности JWT без сохранения состояния. Недавно возникла проблема: токен аутентификации должен получить имя пользователя из токена, но срок действия токена может быть просрочен. Как правило, для получения имени пользователя используется следующий код.
private Claims getClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
}
Если срок действия токена не истек, имя пользователя можно получить с помощью Claims.getSubject(). Однако, если срок действия маркера истечет, будет выдано исключение ExpiredJwtException, что сделает невозможным получение имени пользователя.
Решение
Глядя на исключение ExpiredJwtException, вы обнаружите, что его родительский класс, ClaimJwtException, инкапсулирует члены класса Claims. Таким образом, пока вызывается метод getClaims(), можно получить объект Claim, а затем можно получить имя пользователя.
public abstract class ClaimJwtException extends JwtException {
public static final String INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was: %s.";
public static final String MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE = "Expected %s claim to be: %s, but was not present in the JWT claims.";
private final Header header;
private final Claims claims;
protected ClaimJwtException(Header header, Claims claims, String message) {
super(message);
this.header = header;
this.claims = claims;
}
protected ClaimJwtException(Header header, Claims claims, String message, Throwable cause) {
super(message, cause);
this.header = header;
this.claims = claims;
}
public Claims getClaims() {
return this.claims;
}
public Header getHeader() {
return this.header;
}
}
Код для получения имени пользователя выглядит следующим образом.
/**
* 从token中获取用户名
*/
public String getUsernameFromToken(String token) {
try {
return getClaimsFromToken(token).getSubject();
} catch (ExpiredJwtException e) {
// 过期则从ExpiredJwtException中取username
return e.getClaims().getSubject();
}
}