Spring Cloud Zuul作为网关所具备的最基本的功能:路由,还具备另外一个核心的功能:过滤器。
过滤器
通过Spring Cloud Zuul实现的路由功能,我们的微服务可以通过统一的API网关入口被客户端访问到了。但是他们的访问权限往往都需要一定的限制,系统并不会将所有的微服务接口都对他们开放。所以使用过滤器构建一个独立的服务来完成权限拦截。
新建AuthFilter.java 继承 ZuulFilter 并重写4个方法:
public class AuthFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accessToken = request.getParameter("accessToken"); if(accessToken == null){ System.out.println("没有权限验证"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); return null; } return null; } }
filterType:过滤器的类型,它决定过滤器在请求的哪个生命周期中执行。这里定义为pre,代表请求在路由之前执行。
filterOrder:过滤器的执行顺序,当请求在一个阶段中存在多个过滤器时,需要根据该方法对所有请求都会生效。实际运用中我么可以利用该函数来指定过滤器的有效范围。
shouldFilter:判断过滤器是否需要被执行,实际运用中可以利用这个函数指定过滤器的范围。
run:过滤器的具体逻辑,ctx.setSendZuulResponse(false)使zuul过滤该请求,不对其进行路由,然后通过setResponseStatusCode设置了返回的状态吗,也可以通过ctx.setResponseBody(body)对其返回内容进行编辑等。
当自定义了过滤器后,还没有生效,需要为其创建具体的bean才能启动该过滤器,比如,在启动类中增加:
@EnableZuulProxy @SpringCloudApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } @Bean public AuthFilter authFilter(){ return new AuthFilter(); } }
重启gateway项目,
http://localhost:8769/api-a/test 显示401
http://localhost:8769/api-a/test?accessToken=david 可以正常显示