springcloud gateway配置跨域

最近使用springcloud全家桶做项目,用起来真的舒服!不过也有些东西要自己琢磨,结合网上大家贡献的博客,官方的资料,和最重要的源码,最重要的源码,最重要的源码!!!

环境:springcloud : Greenwich.SR2

江湖流传有三个版本:

  1. 自定义WebFilter实现
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * description: 跨域访问
 *
 * @author lcy
 * @date 2019/8/12
 */
@Component
public class CrossOriginFilter implements GlobalFilter, Ordered {
    private static final String ALL = "*";
    private static final String MAX_AGE = "18000L";


    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain gatewayFilterChain) {
        ServerHttpRequest request = serverWebExchange.getRequest();
//        if (!CorsUtils.isCorsRequest(request)) {
//            return gatewayFilterChain.filter(serverWebExchange);
//        }
        ServerHttpResponse response = serverWebExchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL);
        headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
        if (request.getMethod() == HttpMethod.OPTIONS) {
            response.setStatusCode(HttpStatus.OK);
            return Mono.empty();
        }
        return gatewayFilterChain.filter(serverWebExchange);
    }

    @Override
    public int getOrder() {
        return -300;
    }
}

经过我测试,这种方法并没有卵用!,可能是我哪里没有用对,如果高人路过,希望指点一二!
2. 配置注入CorsWebFilter

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

/**
 * description:
 *
 * @author lcy
 * @date 2019/8/12
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

可用!!!但是算是比较死板的配置方法!

  1. 配置文件配置江湖流传不能用,经过我小改一番,很好用,主要是稍微看下源码
spring:
  cloud:
    gateway:
      #添加跨域的配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowCredentials: true
            allowedOrigins: "http://192.168.0.141,http://192.168.0.140"
            allowedMethods: "*"
            allowedHeaders: "*"

这里有个allowCredentials: true这个东西是设置允许访问携带cookie的,这点一定要和前端对应!

有很多博友说这种方法没有用,配置进去压根就不起作用!说的没错,但是看下源码,其实还需要点其它的配合才行!!!

源码如下:

package org.springframework.cloud.gateway.config;

import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.cors.CorsConfiguration;

@ConfigurationProperties("spring.cloud.gateway.globalcors")
public class GlobalCorsProperties {
    private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap();

    public GlobalCorsProperties() {
    }

    public Map<String, CorsConfiguration> getCorsConfigurations() {
        return this.corsConfigurations;
    }
}

这个只是提供了一个保存配置的容器,但是并没有配置文件去加载使用这玩意儿。我们要做的就是在第二个配置的基础上使用这个自带的配置文件就行了!
代码很简单,如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GlobalCorsProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;


@Configuration
public class CorsConfig {
    @Autowired
    private  GlobalCorsProperties globalCorsProperties;
    /**
     * 测试,灰度,正式环境使用
     * @return
     */
    @Bean
    @Profile({"test","pre","pro"})
    public CorsWebFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        globalCorsProperties.getCorsConfigurations().forEach((path,corsConfiguration)->source.registerCorsConfiguration(path, corsConfiguration));
        return new CorsWebFilter(source);
    }

}

这样可以修改环境配置,随时也可以配置文件,使用起来还是很舒服的!
以上内容仅供参考,有问题随时指正!

你可能感兴趣的:(spring,cloud)