有没有办法从过期的 JWT 令牌中解析声明?
is there a way to parse claims from an expired JWT token?
如果我们尝试解析 expired JWT
,会导致过期异常。
有没有办法 即使 JWT 已过期也能读取声明。
下面用于解析java中的JWT:
Jwts.parser().setSigningKey(secret.getBytes()).parseClaimsJws(token).getBody();
JWT objects 是 Base64URL 编码的。这意味着您始终可以通过手动 Base64URL 解码来读取 headers 和有效负载。在这种情况下,您将简单地忽略 exp
属性。
例如你可以这样做(我正在使用 Java8 built-in Base64
class,但你可以使用任何外部库,例如 Apache Commons Codec):
Base64.Decoder decoder = Base64.getUrlDecoder();
String src = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImV4cCI6IjEzMDA4MTkzODAifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.2GpoV9q_uguSg0Ku6peI5aZ2qBxO5qOA42zaS25gq_c";
String[] parts = src.split("\."); // Splitting header, payload and signature
System.out.println("Headers: "+new String(decoder.decode(parts[0]))); // Header
System.out.println("Payload: "+new String(decoder.decode(parts[1]))); // Payload
输出为:
Headers: {"alg":"HS256","typ":"JWT","exp":"1300819380"}
Payload: {"sub":"1234567890","name":"John Doe","admin":true}
另请注意,exp
属性设置为 1300819380
,对应于 16 january 2016
。
有更好的方法可以做到这一点。
如果您看到 JWT 异常处理程序 object 例如ExpiredJwtException,预期 object 本身包含以下内容:-
header、声明和消息
因此可以通过此 object 轻松提取声明,即 e.getClaims().getId()
其中 e 是 ExpiredJwtException object.
ExpiredJwtException 构造如下:-
public ExpiredJwtException(Header header, Claims claims, String message) {
super(header, claims, message);
}
示例:-
try{
// executable code
}catch(ExpiredJwtException e){
System.out.println("token expired for id : " + e.getClaims().getId());
}
这可能是旧的,但对于任何面临此问题的人来说,java 的 io.jsonwebtoken
ExpiredJwtException
里面已经有claims了,调用e.getClaims()
即可获取。
如果有人来寻找 jose4j 库,那么下面的工作:
invalidJwtException.getJwtContext().getJwtClaims()
只需在调用 ValidateToken 之前将 TokenValidationParameters 的 ValidateLifetime 属性 设置为 false。
TokenValidationParameters tokenValidationParameters = new TokenValidationParameters();
tokenValidationParameters.ValidateLifetime = false;
JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
那么您可以这样阅读声明:
string name = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Name)).Value;
string email = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Email)).Value;
如果你使用io.jsonwebtoken
你试试我的功能:
public Claims getClaimsFromToken(String token) {
try {
// Get Claims from valid token
return Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
} catch (ExpiredJwtException e) {
// Get Claims from expired token
return e.getClaims();
}
}
如果我们尝试解析 expired JWT
,会导致过期异常。
有没有办法 即使 JWT 已过期也能读取声明。
下面用于解析java中的JWT:
Jwts.parser().setSigningKey(secret.getBytes()).parseClaimsJws(token).getBody();
JWT objects 是 Base64URL 编码的。这意味着您始终可以通过手动 Base64URL 解码来读取 headers 和有效负载。在这种情况下,您将简单地忽略 exp
属性。
例如你可以这样做(我正在使用 Java8 built-in Base64
class,但你可以使用任何外部库,例如 Apache Commons Codec):
Base64.Decoder decoder = Base64.getUrlDecoder();
String src = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImV4cCI6IjEzMDA4MTkzODAifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.2GpoV9q_uguSg0Ku6peI5aZ2qBxO5qOA42zaS25gq_c";
String[] parts = src.split("\."); // Splitting header, payload and signature
System.out.println("Headers: "+new String(decoder.decode(parts[0]))); // Header
System.out.println("Payload: "+new String(decoder.decode(parts[1]))); // Payload
输出为:
Headers: {"alg":"HS256","typ":"JWT","exp":"1300819380"}
Payload: {"sub":"1234567890","name":"John Doe","admin":true}
另请注意,exp
属性设置为 1300819380
,对应于 16 january 2016
。
有更好的方法可以做到这一点。 如果您看到 JWT 异常处理程序 object 例如ExpiredJwtException,预期 object 本身包含以下内容:- header、声明和消息
因此可以通过此 object 轻松提取声明,即 e.getClaims().getId()
其中 e 是 ExpiredJwtException object.
ExpiredJwtException 构造如下:-
public ExpiredJwtException(Header header, Claims claims, String message) {
super(header, claims, message);
}
示例:-
try{
// executable code
}catch(ExpiredJwtException e){
System.out.println("token expired for id : " + e.getClaims().getId());
}
这可能是旧的,但对于任何面临此问题的人来说,java 的 io.jsonwebtoken
ExpiredJwtException
里面已经有claims了,调用e.getClaims()
即可获取。
如果有人来寻找 jose4j 库,那么下面的工作:
invalidJwtException.getJwtContext().getJwtClaims()
只需在调用 ValidateToken 之前将 TokenValidationParameters 的 ValidateLifetime 属性 设置为 false。
TokenValidationParameters tokenValidationParameters = new TokenValidationParameters();
tokenValidationParameters.ValidateLifetime = false;
JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
那么您可以这样阅读声明:
string name = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Name)).Value;
string email = principal.Claims.FirstOrDefault(e => e.Type.Equals(ClaimTypes.Email)).Value;
如果你使用io.jsonwebtoken
你试试我的功能:
public Claims getClaimsFromToken(String token) {
try {
// Get Claims from valid token
return Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
} catch (ExpiredJwtException e) {
// Get Claims from expired token
return e.getClaims();
}
}