上篇我们记录了Zuul实现路由转发,这篇我们记录Zuul实现服务过滤
为什么要过滤呢,我们对外开放的服务需要一些安全措施来保护客户端只能访问它应该访问的资源。所以我们需要利用Zuul的过滤器来实现我们对外服务的安全
我们只需要继承ZuulFilter并实现它的四个方法即可实现请求拦截与过滤
package com.chunying.zuul.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.http.HttpServletRequest;
/**
* @author chunying
*/
public class AccessFilter extends ZuulFilter{
public static final Log LOG = LogFactory.getLog(AccessFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
LOG.info(String .format("request is " + request.getMethod()) + request.getRequestURL().toString());
String token = request.getParameter("token");
if(token == null) {
LOG.info("access token is empty");
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
LOG.info("access token is OK");
return null;
}
}
我做了一个简单的校验 如果参数中没有token值,就拒绝访问,返回401 。
其中重写了四个方法我们逐一说一下
filterType():返回一个字符串代表过滤器的类型,在zull中定义了四种不同的类型
pre:可以在请求被路由之前调用
routing:在路由请求时被调用
error:处理请求时发生错误时调用
post:在routing和error过滤器之后被调用
filterOrder():通过int值来定义过滤器的执行顺序
shouldFilter:返回一个boolean值来判断该过滤器是否要执行,所以通过此函数可以实现过滤器的开关。在我的例子中,直接返回true,所以总是生效。
run:过滤器的具体逻辑实现。我们这里只是设置了ctx.setSendZuulResponse(false)
令zuul过滤该请求,然后设置了返回码,我们也可以通过其他方法比如setResponseBody(xxx)对返回body内容进行编辑等。
实现了过滤器 我们还需要实例化它才能生效,我们需要在主类中增加方法(getAccessFilter())返回实例
package com.chunying.zuul;
import com.chunying.zuul.filter.AccessFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
@Bean
public AccessFilter getAccessFilter() {
return new AccessFilter();
}
}
这样就可以启动项目进行测试了
访问http://localhost:8766/api-a/hello?name=ying
请求失败并且返回401错误码
加上token参数
正常返回了
zuul就暂时学到这里啦。我会继续努力的哈