spring cloud gateway跨域全局CORS配置方式

网友投稿 697 2022-10-11


spring cloud gateway跨域全局CORS配置方式

在Spring 5 Webflux中,配置CORS,可以通过自定义WebFilter实现:

注:此种写法需真实跨域访问,监控header中才会带相应属性。

代码实现方式

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.server.reactive.ServerHttpRequest;

import org.springframework.http.server.reactive.ServerHttpResponse;

import org.springframework.web.cors.reactive.CorsUtils;

import org.springframework.web.server.ServerWebExchange;

import org.springframework.web.server.WebFilter;

import org.springframework.web.server.WebFilterChain;

import org.springframework.http.HttpMethod;

import reactor.core.publisher.Mono;

import static org.springframework.web.cors.CorsConfiguration.ALL;

public class XXXApplication{

public static void main(String[] args) {

SpringApplication.run(XXXApplication.class, args);

}

private static final String MAX_AGE = "18000L";

@Bean

public WebFilter corsFilter() {

return (ServerWebExchange ctx, WebFilterChain chain) -> {

ServerHttpRequest request = ctx.getRequest();

if (!CorsUtils.isCorsRequest(request)) {

return chain.filter(ctx);

}

HttpHeaders requestHeaders = request.getHeaders();

ServerHttpResponse response = ctx.getResponse();

HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();

HttpHeaders headers = response.getHeaders();

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());

headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());

if (requestMethod != null) {

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());

}

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");

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 chain.filter(ctx);

};

}

}

配置实现方式

网上还提到一种配置写法,实测好用:

spring:

cloud:

gateway:

globalcors:

corsConfigurations:

'[/**]':

allowedOrigins: "*"

allowedMethods: "*"

allowedHeaders: "*"

springcloud gateway 跨域的解决

springcloud gateway提供的自带的跨域过滤器有问题,前端还是会报跨域。zuul不会有这个问题。调试发现主要是游览器发送嗅探请求(OPTIONS)时,没有返回跨域的响应头,从而游览器报跨域问题。

验证

由于springcloud gateway为webflux与zuul不一样,同一个服务,采用spring内置的跨域过滤器,zuul可以通过而gateway报错。具体配置如下:

1、gateway跨域配置

spring:

cloud:

gateway:

globalcors:

cors-configurations:

'[/**]':

# 允许携带认证信息

# 允许跨域的源(网站域名/ip),设置*为全部

# 允许跨域请求里的head字段,设置*为全部

# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部

# 跨域允许的有效期

allow-credentials: true

allowed-origins: '*'

allowed-headers: Content-Type,Content-Length, Authorization, Accept,X-Requested-With

allowed-methods: '*'

exposed-headers: Content-Type,Content-Length, Authorization, Accept,X-Requested-With

max-age: 3600

此配置无效,前端还是会报跨域问题,主要是前端发送OPTIONS请求时没有返回跨域信息

2、zuul网关或者其它微服务servlet

向容器中注入跨域过滤器

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.core.Ordered;

import org.springframework.web.cors.CorsConfiguration;

import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import org.springframework.web.filter.CorsFilter;

/**

* @author ZhouChuGang

* @version 1.0

* @project langangkj-commonm

* @date 2020/5/4 12:24

* @Description 跨域过滤器配置

*/

@Slf4j

@configuration

@ConditionalOnMissingBean(CorsFilter.class)

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

public class CorsFilterConfiguration {

public CorsFilterConfiguration() {

log.info("==========注入跨域过滤器=============");

}

@Bean("corsFilter")

public CorsFilter corsFilter() {

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

CorsConfiguration config = new CorsConfiguration();

// #允许向该服务器提交请求的URI,*表示全部允许

config.addAllowedOrigin(CorsConfiguration.ALL);

// 允许cookies跨域

config.setAllowCredentials(true);

// #允许访问的头信息,*表示全部

config.addAllowedHeader(CorsConfiguration.ALL);

// 允许提交请求的方法,*表示全部允许

config.addAllowedMethod(CorsConfiguration.ALL);

source.registerCorsChttp://onfiguration("/**", config);

return new CorsFilter(source);

}

@Autowired

@Qualifier("corsFilter")

private CorsFilter corsFilter;

/**

* 配置跨域过滤器

*/

@Bean

public FilterRegistrationBean corsFilterRegistration() {

FilterRegistrationBean registration = new FilterRegistrationBean<>();

registration.setFilter(corsFilter);

registration.addUrlPatterns("/*");

registration.setName("corsFilter");

registration.setOrder(Ordered.HIGHEST_PRECEDENCE);

return registration;

}

}

此方案可以完美解决跨域问题。但是springcloud gateway 不是servlet 规范。

解决方案

1、gateway后面的微服务实现跨域

跨域由网关后面的服务实现。

2、实现一个过滤器,来做跨域允许

需要在响应头中加入以下信息

# 这个为请求头中的 origin

add_header 'Access-Control-Allow-Origin' '$http_origin' ;

add_header 'Access-Control-Allow-Credentials' 'true' ;

add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS' ;

add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With' ;

3、采用nginx做代理,配置跨域响应头。(强烈推荐)

请求先到nginx,nginx再去请求gateway, 由nginx添加跨域响应头

add_header 'Access-Control-Allow-Origin' '$http_origin' ;

add_header 'Access-Control-Allow-Credentials' 'true' ;

add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS' ;

add_hhttp://eader 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With' ;

这里本人为了方便,采用第3中方案,测试完美解决!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:融云推出实时社区解决方案,垂直兴趣社交「高级玩家」上线
下一篇:医疗行业数据安全最佳实践案例(脱敏版)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~