SpringCloud(Finchley.SR2版本)踩坑笔记(七)------- zuul Filter

之前我们配置过 zuul 作为 api 网关 《SpringCloud(Finchley.SR2版本)踩坑笔记(四)------- zuul基础》,zuul 还可以自定义一系列的过滤器,来对请求做一些预先或者后续的处理。

zuul 的 filter 类型分为:

1. pre:在请求被路由之前过滤,可以通过这种过滤器来处理一些类似签名校验,用户身份认证等操作。

2. route:这种过滤器用于构建发送给微服务的请求。

3. post:这种过滤器在微服务有返回结果时过滤,可以用来处理一些标准的 http header,记录返回值之类的操作。

4. error:顾名思义,在发成错误时触发的过滤器。

定义一个 Filter 需要继承 ZuulFilter

public class SignatureFilter extends ZuulFilter {

    public SignatureFilter() {
        // 构造函数
    }

    @Override
    public String filterType() {
        // 定义 filter 的类型
        return FilterConstants.PRE_TYPE; // 可以在请求被路由之前调用
    }

    @Override
    public int filterOrder() {
        // filter 执行顺序,数字越小优先级越高
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        // 是否要被过滤,可以增加自己的业务逻辑判断最后返回 true or false
        return true;
    }

    @Override
    public Object run() {
        // 过滤逻辑实现
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        ctx.setSendZuulResponse(true);
        ctx.setResponseStatusCode(200);

        return null;
    }

}

这样一个自定义的 Filter 就完成了。

很多情况下,我们开发的微服务接口都需要做跨域请求的处理,在 zuul 中,可以通过自定义 Filter 的方式来解决,也可以通过如下方式来自定义一个config解决。

@Configuration
public class CorsConfig {
    
    private final Logger LOGGER = LoggerFactory.getLogger(ZuulApplication.class);
    
    @Bean
    public CorsFilter corsFilter() {
        LOGGER.info("zuul add cors config");
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }
}

跨域请求中,关键是服务器将 response 设置 header  ACCESS_CONTROL_ALLOW_ORIGIN 为正确的值,但是在上述配置的注释信息中可以得知,addAllowedOrigin("*") 在 springmvc 中会自动设置为 request header 的 origin,这时你可能在客户端的请求中发现 response.header 中的 ACCESS_CONTROL_ALLOW_ORIGIN 会有两个值,导致跨域请求在前端认为失败。原因是 zuul 又将这个 header 写了一遍,解决的方法是配置 zuul 的 sensitiveHeaders

zuul:
  routes:
    app-server:
      path: /test-server/**
      sensitiveHeaders: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
      serviceId: test-server
      stripPrefix: false

这样就能解决了,当然也可以直接配置  zuul.sensitiveHeaders 做全局配置。

sensitiveHeaders 的作用是将设置的 header 不向下层微服务传递。还有一个配置是 ignoredHeaders,这里面的 header 会向下层微服务传递,但是微服务再次转发的时候就不会有了。

另外 stripPrefix 的作用是影响传递到微服务的请求地址,比如一个请求:http://zuul-server/test-server/test,stripPrefix = false,那么微服务获得的地址就是 /test-server/test,如果为 true, 那么微服务获得地址就是 /test

你可能感兴趣的:(Spring,Cloud,Spring,Cloud)