Gateway网关(跨域、过滤)

断言工厂

在配置application.yml文件

spring:
	cloud:
		gateway:
			routes:
			- id: user-service #随便起的
			 uri: lb://userservice #服务名称
       		 predicates: 
       		 - Path=/user/** 
       		 filters: # 过滤器
       		 - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头	

当前配置属于访问网关接口,并只有访问user路径下的内容才可访问

如果要对所有路由都生效,则可以将过滤器工厂写道defaul下

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, Itcast is freaking awesome! 
  • 依赖

    <!--网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--nacos服务发现依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  • application.yml

    # 注册到nacos
    spring:
    	application:
    		name: gateway
    	cloud:
    		nacos:
    			server-addr: localhost:8848
    		gateway:
    			routes:
    				- id: user-service #路由id自定义
    				  uri: lb://服务名
    				  predicates:
    				  	- Path=/user/** # 断言规则
    

    这里配置后,根据配置路由把所有的服务集中到网关访问

    也就是说,我们访问网关服务的端口,就可以直接访问到其他服务

    那么,predicates,这里断言规则,也就说,当我访问该端口是必须按照一定的规则去访问,否则他就会出现错误

过滤器工厂

spring:
	cloud:
		gateway:
		routes:
        	- id: user-service #路由id自定义
        	uri: lb://服务名
        	predicates:
        	- Path=/user/** # 断言规则
        	# 过滤器
        	filters:
        		- AddRequestHeader=Truth,Itcast is freaking awesome! # 添加请求头

当前过滤器配置,写在了user-service下,那么也就是说该过滤器只对userservice的请求有效过滤,其他路由不能使用

若要对所有服务都可过滤,需要将过滤器工厂写到default下

spring:
	cloud:
		gateway:
		routes:
        	- id: user-service #路由id自定义
        	uri: lb://服务名
        	predicates:
        	- Path=/user/** # 断言规则
        	# 过滤器
        	default-filters:
        		- AddRequestHeader=Truth,Itcast is freaking awesome! # 添加请求头
  • 过滤器作用

    对路由请求或响应做加功处理,比如添加请求头

  • 全局过滤作用

    定义方法实现接口

    import com.alibaba.fastjson.JSONObject;
    import com.dragon.common.R;
    import lombok.Data;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.annotation.Order;
    import org.springframework.core.io.buffer.DataBuffer;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    import java.nio.charset.StandardCharsets;
    
    @Component
    @Order(-1)
    @Data
    public class BookFilter implements GlobalFilter{
    //    private String[] url;
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String allPath = exchange.getRequest().getURI().getPath();
            System.out.println(allPath);
            //路劲包含book放行
            if (allPath.contains("book")){
                return chain.filter(exchange);
            }
            ServerHttpResponse resp = exchange.getResponse();
            return authErro(resp,"拦截");
        }
        /**
         * 认证错误输出
         * @return
         */
        private Mono<Void> authErro(ServerHttpResponse resp, String mess) {
            resp.setStatusCode(HttpStatus.UNAUTHORIZED);
            resp.getHeaders().add("Content-Type","application/json;charset=UTF-8");
    //        String returnStr = message;
            JSONObject jsonObject = new JSONObject();
    
            jsonObject.put("data",R.error(mess));
            byte[] bytes = jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);
    
            DataBuffer wrap = resp.bufferFactory().wrap(bytes);
            resp.setStatusCode(HttpStatus.OK);
            resp.getHeaders().add("Content-Type","application/json;charset=UTF-8");
            return resp.writeWith(Mono.just(wrap));
        }
    }
    

跨域

  • application.yml

    gateway:
          globalcors:
            add-to-simple-url-handler-mapping: true #解决option拦截请求问题
            cors-configurations:
              '[/**]':
                allowedOrigins: # 允许哪些网站的跨域请求
                  - "http://localhost:5500"
                allowedMethods: # 允许的跨域ajax的请求方式
                  - "GET"
                  - "POST"
                  - "DELETE"
                  - "PUT"
                  - "OPTIONS"
                allowedHeaders: "*" # 允许在请求中携带的头信息
                allowCredentials: true # 是否允许携带cookie
                maxAge: 360000 # 这次跨域检测的有效期
          routes: # 网关路由配置
            - id: service-order # 路由id,自定义,只要唯一即可
              # uri: http://localhost:8081 # 路由的目标地址 http就是固定地址
              uri: lb://service-order # 路由的目标地址 lb就是负载均衡,后面跟服务名称
              predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
                - Path=/service_order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
    
  • 或者配置类进行跨域

    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;
    
    @Configuration
    public class CorsConfig {
        @Bean
        public CorsWebFilter corsWebFilter(){
            CorsConfiguration config = new CorsConfiguration();
            config.addAllowedMethod("*");
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
    //        config.addExposedHeader("**");
    
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
            source.registerCorsConfiguration("/**", config);
    
            return new CorsWebFilter(source);
        }
    }
    
posted @ 2022-11-10 15:36  DawsonDragon  阅读(163)  评论(0)    收藏  举报