springcloud gateway版本
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
跨域问题说明
application:1 Access to XMLHttpRequest at 'https://xxxxxxxxxx' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这里仅说明在同一注册中心注册的服务,网关可以通过在注册中心的服务名称对应找到服务进行路由转发,因此这种情况,不存在跨域问题。
但是对于一些通过nginx反向代理到网关服务下的请求进行访问时,就存在跨域问题。所以下面网关
跨域的原理和理论待补充
什么是域
域是由网络上的用户和计算机组成的一个逻辑或逻辑集合,域中所有的对象都存储在活动目录下,一个网络可以建立一个或者多个域,每个域都是一个安全界限,意味着各种权限不能跨域。
URL
URL:Uniform Resource Locator,统一资源定位器,他是www的统一资源定位标志,就是指网络地址。
URL组成:协议、主机、端口、路径【http://www.baidu.com:80】
(服务类型(HTTP或者HTTPS://主机名(域名或者IP地址)[:端口号]/文件路径/资源名称?参数=参数值&参数=参数值#片段标志符
在www.baidu.com的域名中,com成为顶级域名,baidu称为2级域名,www称为3级域名
跨域是什么?
跨域概念:
跨域是指浏览器不能执行其他网站的脚本,是因为浏览器的同源策略造成的,是浏览器的安全限制
同源概念
同源概念:域名、协议、端口号均相同
注: 二级域名不同,发起请求也是跨域请求,可以在header里面添加域名限制,也可以修改domain
将子域和主域的document.domain设为同一个主域
前提条件: 这两个域名必须属于同一个基础域名,而且所用的协议,端口号都要一致,否则无法利用document.domain进行跨域
所以当协议,子域名,主域名,端口号中任意-各不相同,都算不同的域。他们之间请求资源都是跨域。
为什么有跨域
为了安全,浏览器执行javascript脚本的时候,会检查这个脚本属于哪个页面,不是同源页面,就不会被执行。
同源策略的主要目的是为了防止XSS(跨站脚本攻击)【反射性,非反型、基于DOM】、CSRF(跨域请求伪造等恶意攻击)
但是在实际开发中,经常会有跨域加载资源的需求,比如我们直接使用饮用
网关跨域解决
针对跨域问题,这里提供两种解决方案,仅供参考
方案一 网关proties文件添加配置
spring cloud gateway提供了可以直接通过在yaml文件中配置的方式解决跨域问题,具体的类配置可以查看源码中对应的类org.springframework.cloud.gateway.config.GlobalCorsProperties,源码地址如下:
源码地址
网关配置如下
# 解决Option请求被拦截的问题
spring.cloud.gateway.globalcors.corsConfigurations.[/**].add-to-simple-url-handler-mapping = true
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedOrigins = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedHeaders = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].exposedHeaders = X-trace-id
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedMethods = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].maxAge = 3600
说明:
由于spring-framework从5.3.0版本开始,关于CORS跨域配置类CorsConfiguration中将allowedOrigins变量名修改为allowedOriiginPatterns(spring-framework项目对应的类信息)
spring-framework项目对应的类信息
对于高于5.3.0版本请使用如下配置:
# 解决Option请求被拦截的问题
spring.cloud.gateway.globalcors.corsConfigurations.[/**].add-to-simple-url-handler-mapping = true
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedOriginPatterns = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedHeaders = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].exposedHeaders = X-trace-id
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedMethods = *
spring.cloud.gateway.globalcors.corsConfigurations.[/**].maxAge = 3600
针对此解决方案,官方文档有对应的配置说明,具体可参看下图,下图中红线框出部分需要在配置时注意,记得添加上add-to-simple-url-handler-mapping配置,官方文档地址如下:https://docs.spring.io/spring-cloud-gateway/docs/3.1.4/reference/html/#cors-configuration
方案二:网关注入配置类
Spring Cloud Gateway提供了跨域的配置类,然后在网关项目代码中添加一个CorsWebFilter类即可实现,关于网关提供的Cors配置类,可参看官方文档https://docs.spring.io/spring-framework/docs/5.0.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html)
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
// 这里仅为了说明问题,配置为放行所有域名,生产环境请对此进行修改
config.addAllowedOrigin("*");
// 放行的请求头
config.addAllowedHeader("*");
// 放行的请求方式,主要有:GET, POST, PUT, DELETE, OPTIONS
config.addAllowedMethod("*");
// 暴露头部信息
config.addExposedHeader("*");
// 是否发送cookie
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
注意
配置使用看是否是https或者是http这里可以采用post确认一下