Microservice Gateway (Gateway)

I. Introduction

        In my opinion, in microservices, the gateway is actually the most important thing. It not only does route distribution and load balancing for each service. He can also guarantee the security of our entire microservice. Such as: xxs attack , sql injection . There are also some data that need to be verified in the Request request, cross-domain, global exception handling, etc., all of which need to be written in the gateway.

        The gateway not only provides high concurrency and high availability for microservices. And high security. This time, I will sort out the simple use of Gateway for you. (I can't come if it's too complicated).

xxs attack: It is to change the pages of our website by injecting html language or JavaScript into the request to complete the purpose of hackers.

        We all know that web pages are completed by html tag language, and it is easy to learn. Let's imagine that we don't have xxs interception in web applications. Then random person puts an A tag next to their name when they register their name. like:

<a href="xxxx.com"> Daniel Wu</a>

        Then at this time our website will become a gathering place for p totals. They do the advertising, but we step on the sewing machine. How scary.

        This is my understanding of xxs. I don't know exactly what it is.

------------------------------------------

SQL injection: similar to xxs above, but SQL injection is more difficult to distinguish. Because select is used as a user name for English users, it is normal to appear in the request input parameters. You can't kill all requests with one stick. So at this time, it is necessary to use regular expressions to judge whether the parameters in the user's request constitute a crime, no, whether the configuration constitutes a SQL statement that can be run.

 2. Environment construction

        1. Maven dependency

<!--        Nacos服务注册发现-->
<dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- gateway依赖 没有版本,因为在父工程已指定springBoot版本 -->        
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- 因为我的配置文件是 bootstrap.yml 文件,spring boot版本高后不能自动读取需要这个依赖-->
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

<!--        yml文件中无法通过lb 分发请求问题 解决依赖-->
<dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

        2. Configuration file

server:
  port: 8000                            # 指定gateway网关服务端口
spring:
  application:
    name: spring-myself-gateway         #拟定服务名称
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848     #nacos服务注册地址
    gateway:
      routes:                           #Routes 路由分发功能          
        - id: spring-myself-user        #拟定路由名称,可任意。最好与对应服务,服务名称一致
          uri: lb://spring-myself-user  # lb:负载均衡。后面对应的那nacos注册服务名称。实则URL
          predicates:                    #前言
            - Path=/user/**            #当我们请求gateway服务时前缀如果是这个就会转发上面uri
          filters:                    
            - StripPrefix=1            # 过滤到一层请求 也就是 /user/  


# 我user服务模块端口是8001。 当我们请求 127.0.0.1:8000/user/System/doLogin 时他会通过网关进行转发,转发真实地址: 127.0.0.1:8001/System/doLogin

Third, the use of global filters

        GateWay intimately created the GlobalFilter interface for us. We only need to implement this interface to complete all request filtering.

Code:

        Create the corresponding filter package in our gateway project. Used to write all filters.

@Component  //注入容器
@Slf4j      //日志打印(需要Lombok依赖)   全局过滤,优先等级(值越小越先执行)
public class TestFilter implements GlobalFilter, Ordered {

    //GlobalFilter接口的重写方法
    @Override                //入参理解:  本次请求交互信息,request等          管道
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //根据实际业务条件判断此请求是否继续执行
        if(1==1){
            //return chain.filter(exchange) 正常执行请求
            return chain.filter(exchange);
        }
        //返回null则是对此请求做了过滤,无效了。
        return null;
    }

    //Ordered接口重写,返回int值,值越小越先执行
    @Override
    public int getOrder() {
        return -1;
    }
}

Such a global filter is written. Carry out corresponding release and filter according to actual business

//Get the request from the interaction information 
ServerHttpRequest request = exchange.getRequest();

//Get the response from the interaction information

ServerHttpResponse response = exchange.getResponse();

//Example: Take token information from exchange

String token = exchange.getRequest().getHeaders().getFirst("token");

Access control (black and white list)

               Some requests in the project do not require permission filtering, because the permission filtering of such interfaces will cause the main process to fail. Such as: registration, login and other interfaces. I have all the permissions and the token and still register, why do I log in? So at this point we need to configure the whitelist URL in our yml file. directly in the class. yml. Or data will do. Look at the project, as long as the whitelist list collection can be read. Generally, it is configured in the configuration center, does not need to restart the service, and is convenient for management. Use the @ConfigurationProperties annotation to read it from the yml file and compare it with the current URL request. If it matches, it will be released directly without permission filtering.

        Global filters can be used to prevent xss attacks, blacklists, and whitelists. For configuring cross-domain information, it needs to be implemented through the WebFilter filter.

        Cross-domain configuration: refer to ruoyi-plus

@Component
public class GlobalCorsFilter implements WebFilter, Ordered {

    /**
     * 这里为支持的请求头,如果有自定义的header字段请自己添加
     */
    private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Language, Content-Type, Authorization, credential, X-XSRF-TOKEN, isToken, token, Admin-Token, App-Token";
    private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";
    private static final String ALLOWED_ORIGIN = "*";
    private static final String ALLOWED_EXPOSE = "*";
    private static final String MAX_AGE = "18000L";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if (CorsUtils.isCorsRequest(request)) {
            ServerHttpResponse response = exchange.getResponse();
            HttpHeaders headers = response.getHeaders();
            headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
            headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
            headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
            headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
            headers.add("Access-Control-Max-Age", MAX_AGE);
            headers.add("Access-Control-Allow-Credentials", "true");
            if (request.getMethod() == HttpMethod.OPTIONS) {
                response.setStatusCode(HttpStatus.OK);
                return Mono.empty();
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

Summarize:

        In fact, the functions that need to be configured in the gateway are more than those I mentioned above. The configuration in the gateway is also cumbersome. With my current strength, it's hard to say well. Let's learn as we go.

Guess you like

Origin blog.csdn.net/m0_58907154/article/details/130107884