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确认一下

Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐