Gateway Micro-Service Setup for SpringCloud Project (optional)

5. Gateway Micro-Service Setup (Optional)

5.1 Create Gateway Service Subproject

5.1.1 Introducing Dependency

  • Creating a subproject is just like any other subproject, which is not covered here.

  • In addition to inheriting parent project dependencies, you need to introduce gateway dependencies and Eureka clients:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  • Write a startup class, noting that you need to turn on Eureka client service discovery:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ApiGatewayApplication {
    //ellipsis
    }
    

5.2 Configure Gateway Service

5.2.1 Services and Registration Section

  • Like other services registered with the Eureka service:

    server:
      port: 8086
    spring:
      application:
        name: api-gateway
    eureka:
      client:
        service-url:
          defaultZone: HTTP://127.0.0.1:10086/eureka
      instance:
        prefer-ip-address: true
    

5.2.2 Gateway Configuration

  • This allocation is unique to Spring Cloud Gateway: it is used to configure routing, route predicates-specified requests to the specified id service, and process requests before routing, such as StripPrefix=2, which means the number of prefixes removed from uri is 2.For example:http://localhost:10010/api/user/8 -->http://localhost:9091/8

    server:
      port: 8086
    spring:
      application:
        name: api-gateway
      cloud:
        gateway:
          routes:
            # Route id, optional
            - id: bill-service-route
            # The service address of the proxy (the lb protocol gives the specific ip address via Eureka)
              uri: lb://bill-manager
            # uri: http://127.0.0.1:9091 #Notice the pit, http is just lowercase
            # Routing assertions, mapped paths can be configured
              predicates:
                - Path=/api/**
              filters:
                - StripPrefix=1
    

5.2.3 Gateway inherited ribbon and hystrix configurations

  • If not, the default configuration is taken:

    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 6000 #Service demotion timeout, default 1S
    ribbon:
      ConnectTimeout: 1000 # Connection timeout
      ReadTimeout: 2000 # Data communication timeout
      MaxAutoRetries: 0 # Number of retries for the current server
      MaxAutoRetriesNextServer: 0 # How many service retries
    

5.2.4 Gateway built-in filter

  • In addition to routing management, gateways can also perform filtering behaviors such as authentication. Gateway's built-in filters do not need to be written manually, they only need to be configured in the configuration. Filters configured under routes'specific id routes are local default filters, such as the StripPrefix filter in the example above, and global default filters configured in default-filters.

  • Here is an example of the AddResponseHeader filter that comes with it and works on all routes for the purpose of adding new fields to the response header:

    spring:
      application:
        name: api-gateway
      cloud:
        gateway:
          default-filters:
            - AddResponseHeader=yourKey, yourValue
    
  • The effect of the request is as follows:

5.2.5 Custom Filters

  • Custom global filters do not need to be configured, just write implements GlobalFilter, Ordered:

    @Component
    public class MyGlobalFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            System.out.println("----------Global filter MyGlobalFilter------");
            //The filter checks for token in the request header and lets it go if it does.
            String token = exchange.getRequest().getHeaders().getFirst("token");
            if(StringUtils.isBlank(token)){
                //Set response status code to unauthorized
                exchange.getResponse().setStatusCode(HTTPStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
        @Override
        public int getOrder() {
            //The smaller the value, the earlier the execution
            return 1;
        }
    }
    
  • Customize the local filter, inherit the AbstractGatewayFilterFactory Abstract class, and specify the filter name to configure in the configuration file. Note that the GatewayFilterFactory needs to be omitted from the yml file: in this case, the MyParam filter.

    @Component
    public class MyParamGatewayFilterFactory extends
        AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
        static final String PARAM_NAME = "param";
        public MyParamGatewayFilterFactory() {
            super(Config.class);
        }
        public List<String> shortcutFieldOrder() {
            return Arrays.asList(PARAM_NAME);
        }
        @Override
        public GatewayFilter apply(Config config) {
            return (exchange, chain) -> {
                //Gets the parameter value of the parameter name corresponding to the param in the request parameter
                ServerHTTPRequest request = exchange.getRequest();
                if(request.getQueryParams().containsKey(config.param)){
                    request.getQueryParams().get(config.param).
                        forEach(value -> System.out.printf("Local filter%s=%s", config.param, value));
                }
                return chain.filter(exchange);
            };
         }
         public static class Config{                               
             //Corresponds to the parameter name specified when configuring the filter
            private String param;
            public String getParam() {
                return param;
            }
           	public void setParam(String param) {
                this.param = param;
            } 
         }
    }
    
  • Configure the parameters required for custom filters in the configuration file:

    server:
      port: 8086
    spring:
      application:
        name: api-gateway
      cloud:
        gateway:
          routes:
            # Route id, optional
            - id: bill-service-route
            # The service address of the proxy (the lb protocol gives the specific ip address via Eureka)
              uri: lb://bill-manager
            # uri: http://127.0.0.1:9091 #Notice the pit, http is just lowercase
            # Routing assertions, mapped paths can be configured
              predicates:
                - Path=/api/**
              filters:
                - StripPrefix=1
                - MyParam=name
    
  • In the custom overridden apply method, you can get the parameter name passed to the filter in the configuration file as name, then you can find the corresponding value of the parameter name in all the parameters that visitors bring with them when they visit, so that you can get the values of different parameters in the access request dynamically by changing the configuration file.

5.3 Cross-domain Configuration of Gateway Services

5.3.1 Cross-domain Issues (Browser Issues)

  • **Homology: ** If both pages (interfaces) have the same protocol, port, and domain name, then both pages have the same source.

  • An Ajax request initiated by a page can only have the same path as the current page domain name, which can effectively prevent cross-site attacks.Therefore, cross-domain issues are a limitation on ajax.It is caused by the browser's homology policy and is a security restriction imposed by the browser on JavaScript.

  • Homology restricts the following actions:

    • Cookie s, LocalStorage, and IndexDB are unreadable
    • DOM and JS objects not available
    • Ajax request could not be sent

5.3.2 Gateway Configuration Cross Domain

  • Add in profile:

    spring:
      application:
        name: api-gateway
      cloud:
        gateway:
          default-filters: 
          	#Only versions above Greenwich.SR2 found RETAIN_for duplicate header testingInvalid UNIQUE
            - DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_FIRST
          globalcors:
            cors-configurations:
              '[/api/bill/types]':   #Or full path/**
                allowedOrigins: '*'  #Allow all domains
                allowedHeaders: "*"  #Allow all headers
                allowCredentials: true #Server Open Run Portable Authentication
                allowedMethods:		#Run GET and OPTIONS by default (pre-check request)
                  - POST
                  - GET
                  - PUT
                  - DELETE
              '[/api/bill/test]': 
                allowedOrigins: '*'  #Allow all domains
                allowedHeaders: "*"
                allowCredentials: true
                allowedMethods: '*'
    
  • Note that this configuration method only applies to SpringCloudGateway, and the business microservice in this case requires another method to configure it.

Tags: Java Spring Cloud Java framework gateway

Posted on Tue, 07 Sep 2021 20:38:07 -0400 by drimades