https://www.hdzikao.com

高阶架构师支招:FizzGate的插件开发(JWT的TOKEN续期功能)【fizzgate的插件开发】

[导读] 大家好,今天小热关注到一个比较有意思的话题,就是关于WebUtils的问题,于是小编就整理了2个相关介绍WebUtils的解答,让我们一起看看吧。 文章目录: 高阶架构师支招:FizzGate的插件开发 JW

高阶架构师支招:FizzGate的插件开发(JWT的TOKEN续期功能)【fizzgate的插件开发】

大家好,今天小热关注到一个比较有意思的话题,就是关于WebUtils的问题,于是小编就整理了2个相关介绍WebUtils的解答,让我们一起看看吧。

文章目录:

  1. 高阶架构师支招:FizzGate的插件开发
  2. JWT的TOKEN续期功能

一、高阶架构师支招:FizzGate的插件开发

高阶架构师支招FizzGate插件开发的要点如下

  1. 插件机制理解

    • 灵活插入自定义逻辑:在HTTP请求处理流程中,利用Fizz的插件机制可以灵活地在特定位置插入自定义逻辑。
    • 类似Spring WebFilter:Fizz插件的功能类似于Spring框架中的WebFilter,由Fizz内部进行调度管理。
  2. 插件开发

    • 实现抽象类:在gateway开发中,定义插件需要实现Fizz提供的抽象类。
    • 插件功能实现:例如,测试插件可以对请求ID进行日志记录,并将该信息保存于FIZZRSV头中传递给后端服务。
    • 标记为Spring Component:插件类需要被标记为Spring的Component,并具备一个id属性,用于唯一标识该插件,如testPlugin。
    • 获取前一个插件执行结果:通过Fizz提供的WebUtils方法,当前插件可以获取前一个或指定插件的执行结果,实现插件间的逻辑衔接。
  3. Manager配置

    • 定义插件:在manager配置环节,首先需要定义插件,包括插件的id、中文名和执行顺序。这些信息将用于前端生成配置表单,便于路由配置。
    • 应用插件到接口:将定义好的插件应用到具体的接口中,配置如打印请求ID日志、添加FizzRsv请求头等操作,这些配置将对应到特定的key上。
  4. 参考资源

    • 开源项目:更多关于Fizz Gateway插件开发的具体操作步骤和细节,可以参考Fizz Gateway的开源项目,链接为github.com/wehotel/fizz…。
    • 技术交流群:Fizz官方提供了技术交流群,如Fizz官方技术交流③群:512164278,供开发者进行技术交流和问题解答。

二、JWT的TOKEN续期功能

JWT里有一个关键的东东,就是续期TOKEN,即TOKEN快过期时,刷新一个新的TOKEN给客户端.

办法如下:

1.后端生成TOKEN

importcom.starmark.core.shiro.model.SecurityUser;importcom.starmark.core.shiro.model.UserLoginToken;importcom.starmark.core.shiro.util.JWTUtil;importorg.apache.commons.lang3.BooleanUtils;importorg.apache.commons.lang3.StringUtils;importorg.apache.shiro.authc.AuthenticationException;importorg.apache.shiro.authc.AuthenticationToken;importorg.apache.shiro.subject.Subject;importorg.apache.shiro.web.filter.authc.AuthenticatingFilter;importorg.apache.shiro.web.util.WebUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.web.bind.annotation.RequestMethod;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.util.Date;importjava.util.Objects;publicclassJwtAuthFilterextendsAuthenticatingFilter{privatefinalLoggerlog=LoggerFactory.getLogger(JwtAuthFilter.class);//10分钟后刷新tokenprivatestaticfinalinttokenRefreshInterval=60*10;@OverrideprotectedbooleanpreHandle(ServletRequestrequest,ServletResponseresponse)throwsException{HttpServletRequesthttpServletRequest=WebUtils.toHttp(request);if(httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name()))//对于OPTION请求做拦截,不做token校验returnfalse;returnsuper.preHandle(request,response);}@OverrideprotectedvoidpostHandle(ServletRequestrequest,ServletResponseresponse){request.setAttribute("jwtShiroFilter.FILTERED",true);}@OverrideprotectedbooleanisAccessAllowed(ServletRequestrequest,ServletResponseresponse,ObjectmappedValue){if(this.isLoginRequest(request,response)){returntrue;}BooleanafterFiltered=(Boolean)(request.getAttribute("jwtShiroFilter.FILTERED"));if(BooleanUtils.isTrue(afterFiltered))returntrue;booleanallowed=false;try{allowed=executeLogin(request,response);}catch(IllegalStateExceptione){//not found any tokenlog.error("Not found any token");}catch(Exceptione){log.error("Error occurs when login",e);}returnallowed||super.isPermissive(mappedValue);}@OverrideprotectedAuthenticationTokencreateToken(ServletRequestservletRequest,ServletResponseservletResponse){StringjwtToken=getAuthzHeader(servletRequest);if(StringUtils.isNotBlank(jwtToken)&&!JWTUtil.isTokenExpired(jwtToken))returnUserLoginToken.buildPassword(jwtToken,null,"jwt");returnnull;}@OverrideprotectedbooleanonAccessDenied(ServletRequestservletRequest,ServletResponseservletResponse)throwsException{HttpServletResponsehttpResponse=WebUtils.toHttp(servletResponse);httpResponse.sendRedirect("/unauth");returnfalse;}@OverrideprotectedbooleanonLoginSuccess(AuthenticationTokentoken,Subjectsubject,ServletRequestrequest,ServletResponseresponse){HttpServletResponsehttpResponse=WebUtils.toHttp(response);if(tokeninstanceofUserLoginToken&&"jwt".equalsIgnoreCase(((UserLoginToken)token).getLoginType())){UserLoginTokenjwtToken=(UserLoginToken)token;booleanshouldRefresh=shouldTokenRefresh(Objects.requireNonNull(JWTUtil.getIssuedAt(jwtToken.getUsername())));if(shouldRefresh){//生成新的TOKENSecurityUseruser=(SecurityUser)subject.getPrincipal();StringnewToken=JWTUtil.sign(user.getUserInfo().getId());httpResponse.setHeader("x-auth-token",newToken);}}returntrue;}@OverrideprotectedbooleanonLoginFailure(AuthenticationTokentoken,AuthenticationExceptione,ServletRequestrequest,ServletResponseresponse){log.error("Validate token fail, token:{}, error:{}",token.toString(),e.getMessage());returnfalse;}/**

    * 获取TOKEN

    * @param request 请求

    * @return token

    */privateStringgetAuthzHeader(ServletRequestrequest){HttpServletRequesthttpRequest=WebUtils.toHttp(request);Stringheader=httpRequest.getHeader("x-auth-token");returnStringUtils.removeStart(header,"Bearer ");}/**

    * 判断是否需要刷新TOKEN

    * @param issueAt token签发日期

    * @return 是否需要刷新TOKEN

    */privatebooleanshouldTokenRefresh(DateissueAt){LocalDateTimeissueTime=LocalDateTime.ofInstant(issueAt.toInstant(),ZoneId.systemDefault());returnLocalDateTime.now().minusSeconds(tokenRefreshInterval).isAfter(issueTime);}}

原签发TOKEN后10分钟后刷新新的TOKEN

2.前端获取TOKEN

// 拦截响应response,并做一些错误处理axios.interceptors.response.use((response)=>{if(response.status===200&&response.data&&response.data.code===401){(window.location.origin);window.location.href=window.location.origin+window.location.pathname+'#/login';}//获取返回的TOKENconsttoken=response.headers['x-auth-token'];if(token){//将续期的TOKEN存起来localStorage.setItem("token",token);}// 这里是填写处理信息returnresponse;},(err)=>{// 这里是返回状态码不为200时候的错误处理console.log(err);if(err&&err.response){switch(err.response.data.code){case400:err.message='请求错误';break;case401:err.message='未授权,请登录';break;case403:err.message='无权限';break;case404:err.message=`请求地址出错: ${err.response.config.url}`;break;case408:err.message='请求超时';break;case500:err.message='服务器内部错误';break;case501:err.message='服务未实现';break;case502:err.message='网关错误';break;case503:err.message='服务不可用';break;case504:err.message='网关超时';break;case505:err.message='HTTP版本不受支持';break;default:}}Vue.prototype.$message.error(err.response.data.msg!=null?err.response.data.msg:err.message);returnPromise.reject(err)});

注意一点,需要通过过滤器调整FITLER,增加Access-Control-Expose-Headers的输出,否则无法获取response中的header.

至此,JWT的TOKEN续期功能完成.

到此,以上就是小编对于WebUtils的问题就介绍到这了,希望介绍关于WebUtils的2点解答对大家有用。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读