JWT认证,取得过期token的用户名
- - 掘金后端项目前后端分离,请求认证使用的是JWT无状态认证. 最近遇到一个问题,认证token需要从token中获取用户名,但是这个token有可能是过期的. 一般取得用户名用的是下面的代码. .getBody();
}
复制代码. 如果token没有过期,则可以通过Claims.getSubject()获得用户名.
项目前后端分离,请求认证使用的是JWT无状态认证。最近遇到一个问题,认证token需要从token中获取用户名,但是这个token有可能是过期的。一般取得用户名用的是下面的代码。
private Claims getClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
}
复制代码
如果token没有过期,则可以通过Claims.getSubject()获得用户名。但是token过期,则会抛出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();
}
}
复制代码