• 微服务-gateway跨域配置


    一、前言

    SpringCloud项目中,前后端分离目前很常见,在调试时会遇到前端页面通过不同域名或IP访问微服务的后台,此时,如果不加任何配置,前端页面的请求会被浏览器跨域限制拦截,所以,业务服务常常会添加跨域配置

    二、gateway跨域配置

    1、问题描述

    1.1、什么是跨域请求?

    跨域请求是指来自不同源(域名、端口或协议)的前端应用发起的HTTP请求。由于浏览器的同源策略,这种请求通常被阻止,除非服务器明确允许。因此,当你的前端应用和后端服务位于不同的域时,就会面临跨域问题。

    1.1.1、同源策略

    同源策略是浏览器的一项安全措施,旨在防止恶意网站获取用户的敏感数据或进行恶意操作。同源策略规定,一个网页只能从与其来源相同的域名、端口和协议上加载资源,而不能跨域访问其他域名的资源。同源策略的目的是确保不同源之间的数据和行为隔离,以保护用户的隐私和安全。

    同源策略的要求包括:

    • 协议必须相同(如http和https不同源)。
    • 域名必须相同。
    • 端口号必须相同。
      如果任何一个条件不符合,浏览器将阻止页面通过JavaScript等方式访问其他源的资源。这就是为什么在开发Web应用时,跨域请求会遇到问题的原因之一。
    1.1.2. 安全性考虑

    跨域问题的另一个原因是安全性考虑。当一个网站允许其他网站通过跨域请求来访问其资源时,存在潜在的安全风险。例如,如果一个网站允许跨域访问其用户数据,恶意网站可以利用这一漏洞来窃取用户的敏感信息。因此,浏览器实施同源策略,限制跨域请求,以减少这种风险。

    1.1.3. 跨域攻击

    跨域请求还可能导致跨站请求伪造(Cross-Site Request Forgery,CSRF)攻击。CSRF攻击是一种利用用户在已登录的状态下,误导用户发起恶意请求的攻击方式。如果没有适当的跨域控制,攻击者可以伪装成受害者,向其他网站发送请求,以执行未经授权的操作。

    1.2、问题产生原因

    前端页面地址:http://127.0.0.1:5173/
    后端接口地址:http://127.0.0.1:9081/xxxxx
    由于浏览器的同源策略,现在是端口不一致导致的跨域问题;
    在这里插入图片描述
    前端调用后端接口的js:
    在这里插入图片描述
    在这里插入图片描述

    2、解决方法

    2.1、修改配置文件

    在gateway的配置文件中增加跨域配置:
    globalcors: cors-configurations: '[/**]': allowedOrigins: "*" allowedHeaders: "*" allowedMethods: "*" default-filters: - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST

    server:
      port: 9081
      servlet:
        context-path: /gateway-demo
    spring:
      application:
        name: gateway-demo
      cloud:
        nacos:
          discovery:
            server-addr: 124.70.79.190:8848
            namespace: wangmengjie
        gateway:
          globalcors:
            cors-configurations:
              '[/**]':
                allowedOrigins: "*"
                allowedHeaders: "*"
                allowedMethods: "*"
          default-filters:
            - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
          discovery:
            locator:
              enable: true #让gateway可以发现nacos中的微服务
          routes: #路由,数组[这里可以放置多个路由]
            #评分管理模块网关路由配置
            - id: user-router #当前路由标识-要求唯一,默认是UUID;
              uri: lb://user-demo #请求最终要被转发的地址;
              order: 1 #路由的优先级——数字越小,代表路由的优先级越高
              predicates: #断言:(条件判断——转发请求要满足的条件)
                - Path=/user-service/** #当请求路径满族path指定的规则时,此路由信息才会正常转发;
              filters: #过滤器,是在请求传递过程中对请求做一些手脚;
                - StripPrefix=1 #在请求转发之前去掉一层路径
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    再次进行调用看一下结果:可以看到,接口现在正常返回结果了。
    在这里插入图片描述

    2.2、配置类统一配置

    @Configuration
    public class FdmallCorsConfiguration {
        /**
         * 添加跨域过滤器
         * @return
         */
        @Bean // 添加过滤器
        public CorsWebFilter corsWebFilter(){
            //基于url跨域,选择reactive包下的
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            // 跨域配置信息
            CorsConfiguration configuration = new CorsConfiguration();
            // 允许跨域的头
            configuration.addAllowedHeader("*");
            // 允许跨域的请求方式
            configuration.addAllowedMethod("*");
            // 允许跨域的请求来源
            configuration.addAllowedOrigin("*");
            // 是否允许携带cookie跨域
            configuration.setAllowCredentials(true);
            // 任意url都要进行跨域配置
            source.registerCorsConfiguration("/**", configuration);
            return new CorsWebFilter(source);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    检查请求是否为OPTIONS方法(预检请求)。如果是,我们返回HTTP状态码200 OK,以满足浏览器的预检请求。

    设置允许的来源(Access-Control-Allow-Origin)为"*",这意味着允许来自任何域的请求。在生产环境中,应根据需要将其设置为特定的域名。

    设置允许的HTTP方法(Access-Control-Allow-Methods),通常是GET、POST、PUT、DELETE和OPTIONS。

    设置允许的HTTP头信息(Access-Control-Allow-Headers),通常是Content-Type和Authorization。
    注: SpringCloudGateWay中跨域配置不起作用,原因是SpringCloudGetway是Springwebflux的而不是SpringWebMvc的,所以我们需要导入的包导入错了。

    2.3、全局跨域拦截器

    @Order(10)
    @Component
    public class CorsResponseHeaderFilter implements GlobalFilter {
        private static final String ANY = "*";
        @Override
        @SuppressWarnings("serial")
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                exchange.getResponse().getHeaders().entrySet().stream()
                        .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
                        .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
                                || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
                                || kv.getKey().equals(HttpHeaders.VARY)))
                        .forEach(kv ->
                        {
                            // Vary只需要去重即可
                            if(kv.getKey().equals(HttpHeaders.VARY))
                                kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList()));
                            else{
                                List<String> value = new ArrayList<>();
                                if(kv.getValue().contains(ANY)){  //如果包含*,则取*
                                    value.add(ANY);
                                    kv.setValue(value);
                                }else{
                                    value.add(kv.getValue().get(0)); // 否则默认取第一个
                                    kv.setValue(value);
                                }
                            }
                        });
            }));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    三、总结

    在Web应用程序中,跨域请求是一个常见的问题。当两个不同的域之间进行通信时,由于浏览器的同源策略,会出现跨域问题。在Spring Cloud Gateway中,可以通过配置来解决这个问题。Spring Cloud Gateway是Spring Cloud生态系统中提供的一种API网关,它可以对进出应用程序的所有请求进行拦截、管理和路由。通过配置,可以实现对请求的过滤、认证、路由、限流等功能。

    如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。

  • 相关阅读:
    flutter tabbar设置indicator高度、宽度
    打破AI算力成本困局 趋动科技即将重磅发布全球首个AI算力池化云服务
    Flutter 编写收音机开源
    websocket接口测试
    一个开源的音频分离深度学习项目
    GBase 8c 备份控制函数(三)
    基于QT实现的银行储蓄管理系统
    举报即有机会解锁CSDN限定勋章|2022上半年CSDN社区治理数据公布
    多台机器下本地缓存一致性解决(附带源码链接)
    2023艾灸展/中国山东·济南国际艾灸仪器设备与艾制品展览会
  • 原文地址:https://blog.csdn.net/wmj20001225/article/details/132661789