java过滤器全局分析token
使用过滤器定义全局token解析器
在后端接口的开发过程中,一般涉及个人用户,在权限和安全方面考虑的接口使用token传递用户和安全系数高的认证参数等。
一般接口定义
全局AOP分析
使用AOP对需要获取token信息的接口进行方法扩展,在进入控制器之前动态验证接口方法,或将token相关参数添加到接口方法中。
需要的参数因需求而异。 这个可以根据业务来。 这方面的代码也很多。 原理是在方法执行前进行token认证,以及添加和提取参数。 业务复杂的时候,可以自己拓展想象,自己做。
界面使用注释@RequestHeader
另一种方法是,每个接口自己处理token的验证或参数提取,在请求参数中声明从header获取的值,并在方法内部进行分析
@getmapping('legend ' ) ) ) ) ) ) ) )。
publicresponsegettheshy (@ requestheaderstringtoken,@RequestParam ) ) (字符串顶部)。
解析token的认证。
//业务
返回空值;
}
如果不害怕故障,或者需要token的接口很少,可以考虑使用这种方法。 对于微服务来说,token认证可能是另一种服务,或者需要调用其他方法,并且可能需要封装这种方法,但实际上没关系。
我的需要和方法
需求和现状
业务几乎是所有对外的,界面需要用户的信息,例如用户ID或用户名
解析和分发token的业务不是我的模块。 我获得的token是从网关分发到守护程序的token,需要依赖网关的服务才能解决
只需要token分析的用户所在的信息
所有接口都不想知道token是如何分析的,参数是如何获取的
实践
使用筛选器控制请求参数的获取,并控制请求参数的值
控制层代码
具体代码:
控制器:
@getmapping('top ) ) ) ) ) )。
publicresponseGettheshy{
log.info(Token );
returntopservice.gettheshy (token );
}
控制层接口直接声明我所需的用户信息,也就是需要从token解析的数据
过滤器代码
具体代码:
@Component
@webfilter(filtername='token ',urlPatterns={'/*'}
publicclassfilterconfigcontrollerimplementsfilter {
privatestaticloggerlog=logger factory.getlogger (filterconfigcontroller.class );
@Override
公共语音输入(filterconfigfilterconfig )
log.info (“过滤器初始化”);
}
@Override
publicvoiddofilter (servletrequestservletrequest,ServletResponse servletResponse,过滤器通道过滤器通道) throws IOException
httpservletrequestwrapperrequestwrapper=newhttpservletrequestwrapper ((http服务器请求) servletrequest ) {
@Override
公共地图获取参数地图
return super.getParameterMap (;
}
@Override
公共字符串获取参数(字符串名称) {
returnsuper.getparameter(name;
}
@Override
公共字符串[ ] getparameter values {
if(Token ).equals(name ) () }
string token=this.get header (' token );
//取得认证或token
if(stringutils.isempty(t
oken)){log.error("缺少token");
throw new MyRuntimeException(ErrorCode.ERROR_AUTH_NULL_TOKEN);
}
if ("token".equals(name)){
//具体的解析token逻辑
}else if ("userId".equals(name)){
//具体的解析token逻辑
}
return new String[]{token};
}
return super.getParameterValues(name);
}
@Override
public String getQueryString() {
return super.getQueryString();
}
};
filterChain.doFilter(requestWrapper,servletResponse);
}
}
继承Filter,并实现其方法,主要对 doFilter方法中的getParameterValues方法重写
该方法的作用就是,如果你得controller需要一个参数值时,会从这里获取,所以我们可以对此进行自定义的参数获取。
规定好我们要获取的参数名称,可以叫做token,然后这边对这个参数名进行拦截,当需要获取我们指定参数名称的值时,由下面代码生成
下面的代码就是从请求头获取token,然后鉴权和获取用户信息的具体实现
如果请求头的token不满足我们的需求,或者解析失败,就可以直接返回前端,而不用进入controller
6.我采用的直接返回前端的方法是,直接在过滤器中抛出一个自定义的运行时异常(此方法不允许有异常,只能抛运行时异常)
由全局的异常处理,来处理抛出的自定义运行时异常,并返回给前端
/**
* 处理运行时异常
* @param e
* @return
*/
@ExceptionHandler
public Response runtimeExceptionMatchHandle(RuntimeException e, HttpServletResponse response){
if (e instanceof MyRuntimeException){
e.printStackTrace();
return Response.failure(((MyRuntimeException) e).getCode());
}
return Response.failure(ErrorCode.ERROR);
}
自定义异常,抛出的时候也把要返回的信息返回
/**
* 自定义运行时异常
*/
public class MyRuntimeException extends RuntimeException{
private ErrorCode code;
public MyRuntimeException(ErrorCode code){
super(code.getMsg());
this.code = code;
}
public ErrorCode getCode() {
return code;
}
}
注意点
如果在controller的参数上加了@RequestParam注解,那么在获取这个参数值的时候不会进入到过滤器的方法中
在其他不需要进入自定义过滤的而参数加上注解,不加也可以,只要名称不一样就不会往下走
要获取的token相关参数,不要加此注解
自定义的过滤器可以多个参数获取只需要在入口处,多加一个参数名称判断,且在返回参数值的时候,根据名称不同返回不同的值即可
如果有问题,欢迎指正,不明白的话可以私信博主