1. 复现错误
今天调用本地接口时,控制台却报出如下的错误:
io.jsonwebtoken.ExpiredJwtException: JWT expired at 2023-04-11T14:59:18+0800. Current time: 2023-04-11T15:16:30+0800
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:365)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518)
at com.test.config.jwt.Jwvider.checkToken(JwtTokenProvider.java:76)
at com.test.controller.AppPageController.pageContentDetail(AppPageController.java:145)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.github.xiaoymin.knife4j.spring.filter.SecurityBasicAuthFilter.doFilter(SecurityBasicAuthFilter.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:114)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:204)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.ssssssss.magicapi.core.config.MagicCorsFilter.doFilter(MagicCorsFilter.java:41)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
......
2. 分析错误
错误信息这么多,我们只需要关注这句话:
io.jsonwebtoken.ExpiredJwtException: JWT expired at 2023-04-11T14:59:18+0800. Current time: 2023-04-11T15:16:30+0800
这是jwt
抛出的异常,根据错误信息可知:
jwt
的预计过期时间是2023-04-11 14:59:18
,而系统的当前时间是2023-04-11 15:16:30
。
换句话说,系统的时间超过了jwt
设置的过期时间。
3. 解决错误
由于系统的时间超过了jwt
设置的过期时间,我们可以采用如下方法解决。
- 重新生成
jwt token
一般情况下,我们在登录时就会创建jwt token
,故需要调用登录接口来获取最新的jwt token
,如下图所示:
复制上图中的token
,调用已写好的checkToken
方法,成功执行,如下图所示:
当然,如果你是在网页上出现这个错误,可以退出账号重新登录即可。
- 延长
jwt token
的失效时间
我们在实际开发中,一般设置时间时间为2小时,我们可以将其修改为12小时。
你可以在application.yml
文件中修改,如下配置所示:
# jwt配置
jwt:
tokenHeader: Authorization # JWT存储的请求头
# 令牌前缀: JWT负载中拿到开头
tokenStartWith: Bearer
#JWT加解密使用的密钥的base64编码
secret: xxxx
expiration: 43200000 #JWT的超期限时间-12小时候超时,以毫秒为单位
typ: JWT
alg: xxx
subject: xxx
当然,你也可以在代码中修改,如下代码所示:
/**
* 创建token
*
* @return 返回jwt token
*/
public String createToken(TokenProperties tokenProperties) {
Date date = new Date(System.currentTimeMillis() + 43200000);
String token =
Jwts.builder()
.setSubject(JSON.toJSONString(tokenProperties))
.setExpiration(date)
.signWith(SignatureAlgorithm.HS512, key)
.compact();
return properties.getTokenStartWith() + SPACING + token;
}
但在实际开发中,我们不建议在代码中修改,因为本地环境、测试环境、线上环境对jwt token
的失效时间的要求是不一样的。
因而,我们一般在application-xxx.yml
配置:
-
application-local.yml
本地环境,可以将失效时间设置久点,比如86400000毫秒(24小时)
,避免在调试接口时反复登录。 -
application-dev.yml
测试环境,也可以将失效时间43200000毫秒(12小时)
-
application-prd.yml
正式环境,可以将失效时间设置为2
小时,也就是7200000
毫秒
4. 补充说明
正赶上最近ChatGPT
比较火,借助他来分析下上述错误,如下图所示: