zhoux 2 år sedan
incheckning
f4a1e21c46

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+/.idea
+/target
+/*.iml
+/log

+ 283 - 0
pom.xml

@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.dk.iboss</groupId>
+    <artifactId>dkic-op-server-gateway</artifactId>
+    <version>3.0.0</version>
+    <name>dkic-op-server-gateway</name>
+    <description>dk iboss gateway server</description>
+
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.6.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <springframework-cloud.version>Hoxton.RELEASE</springframework-cloud.version>
+        <alibaba-cloud.version>2.2.0.RELEASE</alibaba-cloud.version>
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>st</id>
+            <properties>
+                <environment>st</environment>
+            </properties>
+        </profile>
+
+        <profile>
+            <id>uat</id>
+            <properties>
+                <environment>uat</environment>
+            </properties>
+        </profile>
+
+        <profile>
+            <id>prod</id>
+            <properties>
+                <environment>prod</environment>
+            </properties>
+        </profile>
+
+        <profile>
+            <id>test</id>
+            <properties>
+                <environment>test</environment>
+            </properties>
+        </profile>
+
+        <profile>
+            <id>dev</id>
+            <properties>
+                <environment>dev</environment>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault><!-- 默认激活该profile节点-->
+            </activation>
+        </profile>
+    </profiles>
+
+    <dependencyManagement>
+    <dependencies>
+            <!--整合spring cloud-->
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${springframework-cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <!--整合spring cloud alibaba-->
+            <dependency>
+                <groupId>com.alibaba.cloud</groupId>
+                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
+                <version>${alibaba-cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!--项目整合Nacos实现配置管理-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <!--必须加,不加不注册-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <!--lombok-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!--sentinel-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+        <!--redis-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+            <version>2.3.1.RELEASE</version>
+        </dependency>
+        <!--zipkin-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-zipkin</artifactId>
+        </dependency>
+        <!--webflux与webmvc不兼容,需要排除掉,否则会项目启动不起来-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-webmvc</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.tomcat.embed</groupId>
+                    <artifactId>tomcat-embed-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!--webflux-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+        <!--服务发现-->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!--gateway网关-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-gateway</artifactId>
+        </dependency>
+        <!--feign-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <!--loadbalancer-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
+        </dependency>
+        <!-- JWT -->
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource> <!--此处配置到java是因为mapper.xml文件在java目录-->
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+                <filtering>false</filtering>
+            </resource>
+            <resource> <!--项目配置文件-->
+                <directory>src/main/resources/${environment}</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+            <resource> <!--日志配置文件-->
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>com.dk.gateway.GatewayServer</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>1.2.2</version>
+
+                <configuration>
+                    <serverId>aliyun-acr</serverId>
+                    <registryUrl>registry.cn-shenzhen.aliyuncs.com</registryUrl>
+                    <!--依赖的基础镜像-->
+                    <baseImage>java</baseImage>
+                    <!--imageName必须跟仓库路径一致-->
+                    <imageName>registry.cn-shenzhen.aliyuncs.com/hgscrm-${environment}/${project.artifactId}:${project.version}</imageName>
+                    <!-- 指定Dockerfile所在的路径 -->
+                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
+                    <resources>
+                        <resource>
+                            <targetPath>/</targetPath>
+                            <directory>${project.build.directory}</directory>
+                            <include>${project.build.finalName}.jar</include>
+                        </resource>
+                    </resources>
+                    <pushImage>true</pushImage>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <!--恒洁maven私服 haip仓库-->
+            <id>private</id>
+            <name>private</name>
+            <url>http://172.17.216.67:8081/repository/haip</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+
+        <!--maven私服 setting.xml 配置
+        <server>
+            <id>haip</id>
+            <username>haip</username>
+            <password>haip2020</password>
+        </server>-->
+        <!--阿里云仓库-->
+        <repository>
+            <id>aliyun</id>
+            <name>aliyun</name>
+            <url>https://maven.aliyun.com/repository/public</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+        <!--中央仓库-->
+        <repository>
+            <id>central</id>
+            <name>central</name>
+            <url>https://repo1.maven.org/maven2</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+</project>

+ 5 - 0
src/main/docker/Dockerfile

@@ -0,0 +1,5 @@
+FROM java:8
+# COPY jar from the first stage
+ADD mes-gateway-server-1.0-dev.jar mes-gateway-server.jar
+
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/mes-gateway-server.jar"]

+ 22 - 0
src/main/java/com/dk/gateway/GatewayServer.java

@@ -0,0 +1,22 @@
+package com.dk.gateway;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * @desc   : 网关服务主启动类
+ * @author : 张潇木
+ * @date   : 2022-5-24 20:18
+ */
+@EnableDiscoveryClient
+@EnableFeignClients
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class GatewayServer {
+    public static void main(String[] args) {
+        SpringApplication.run(GatewayServer.class, args);
+    }
+}

+ 24 - 0
src/main/java/com/dk/gateway/config/GatewayConfig.java

@@ -0,0 +1,24 @@
+package com.dk.gateway.config;
+
+import com.dk.gateway.decorator.PayloadServerWebExchangeDecorator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.web.server.WebFilter;
+
+/**
+ * @desc   : 日志过滤器配置类
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:03
+ */
+@Configuration
+public class GatewayConfig {
+
+    @Bean
+    @Order(Ordered.HIGHEST_PRECEDENCE) //过滤器顺序
+    public WebFilter webFilter() {
+        return (exchange, chain) -> chain.filter(new PayloadServerWebExchangeDecorator(exchange));
+    }
+
+}

+ 57 - 0
src/main/java/com/dk/gateway/decorator/ParamsUtils.java

@@ -0,0 +1,57 @@
+package com.dk.gateway.decorator;
+
+import io.netty.buffer.UnpooledByteBufAllocator;
+import lombok.Data;
+import org.apache.commons.io.IOUtils;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.core.io.buffer.NettyDataBufferFactory;
+import org.springframework.http.MediaType;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @desc   : 请求参数配置
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:04
+ */
+public class ParamsUtils {
+
+    public static final List<MediaType> CHAIN_MEDIA_TYPE = Arrays.asList(MediaType.TEXT_XML,
+            MediaType.APPLICATION_XML,
+            MediaType.APPLICATION_JSON,
+            MediaType.TEXT_PLAIN,
+            MediaType.TEXT_XML,
+            MediaType.APPLICATION_FORM_URLENCODED
+    );
+
+    public static <T extends DataBuffer> BodyDecorator buildBodyDecorator(T buffer) {
+        try {
+            InputStream dataBuffer = buffer.asInputStream();
+            byte[] bytes = IOUtils.toByteArray(dataBuffer);
+            NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
+            DataBufferUtils.release(buffer);
+            BodyDecorator bodyDecorator = new BodyDecorator(new String(bytes), nettyDataBufferFactory.wrap(bytes));
+            return bodyDecorator;
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Data
+    static class BodyDecorator {
+
+        String body;
+
+        DataBuffer dataBuffer;
+
+        public BodyDecorator(String body, DataBuffer dataBuffer) {
+            this.body = body;
+            this.dataBuffer = dataBuffer;
+        }
+
+    }
+
+}

+ 38 - 0
src/main/java/com/dk/gateway/decorator/PartnerServerHttpRequestDecorator.java

@@ -0,0 +1,38 @@
+package com.dk.gateway.decorator;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import static reactor.core.scheduler.Schedulers.single;
+
+/**
+ * @desc   : 请求装饰器
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:05
+ */
+@Slf4j
+public class PartnerServerHttpRequestDecorator extends ServerHttpRequestDecorator {
+
+    private final Flux<DataBuffer> body;
+
+    public PartnerServerHttpRequestDecorator(ServerHttpRequest delegate) {
+        super(delegate);
+        Flux<DataBuffer> flux = super.getBody();
+            Mono<DataBuffer> mono = DataBufferUtils.join(flux);
+            body = mono.publishOn(single()).map(dataBuffer ->
+                    RequestParamsHandle.chain(delegate, log, dataBuffer)
+            ).flux();
+    }
+
+    @Override
+    public Flux<DataBuffer> getBody() {
+        return body;
+    }
+
+}

+ 48 - 0
src/main/java/com/dk/gateway/decorator/PartnerServerHttpResponseDecorator.java

@@ -0,0 +1,48 @@
+package com.dk.gateway.decorator;
+
+import lombok.extern.slf4j.Slf4j;
+import org.reactivestreams.Publisher;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import static reactor.core.scheduler.Schedulers.single;
+
+/**
+ * @desc   : 响应装饰器
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:05
+ */
+@Slf4j
+public class PartnerServerHttpResponseDecorator extends ServerHttpResponseDecorator {
+
+    PartnerServerHttpResponseDecorator(ServerHttpResponse delegate) {
+        super(delegate);
+    }
+
+    @Override
+    public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
+        return super.writeAndFlushWith(body);
+    }
+
+    @Override
+    public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
+        final MediaType contentType = super.getHeaders().getContentType();
+        if (ParamsUtils.CHAIN_MEDIA_TYPE.contains(contentType)) {
+            if (body instanceof Mono) {
+                final Mono<DataBuffer> monoBody = (Mono<DataBuffer>) body;
+                return super.writeWith(monoBody.publishOn(single()).map(dataBuffer -> ResponseParamsHandle.chain(log, dataBuffer)));
+            } else if (body instanceof Flux) {
+                Mono<DataBuffer> mono = DataBufferUtils.join(body);
+                final Flux<DataBuffer> monoBody = mono.publishOn(single()).map(dataBuffer -> ResponseParamsHandle.chain(log, dataBuffer)).flux();
+                return super.writeWith(monoBody);
+            }
+        }
+        return super.writeWith(body);
+    }
+
+}

+ 35 - 0
src/main/java/com/dk/gateway/decorator/PayloadServerWebExchangeDecorator.java

@@ -0,0 +1,35 @@
+package com.dk.gateway.decorator;
+
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.ServerWebExchangeDecorator;
+
+/**
+ * @desc   : 注入自定义装饰器
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:07
+ */
+public class PayloadServerWebExchangeDecorator extends ServerWebExchangeDecorator {
+
+    private final PartnerServerHttpRequestDecorator requestDecorator;
+
+    private final PartnerServerHttpResponseDecorator responseDecorator;
+
+    public PayloadServerWebExchangeDecorator(ServerWebExchange delegate) {
+        super(delegate);
+        requestDecorator = new PartnerServerHttpRequestDecorator(delegate.getRequest());
+        responseDecorator = new PartnerServerHttpResponseDecorator(delegate.getResponse());
+    }
+
+    @Override
+    public ServerHttpRequest getRequest() {
+        return requestDecorator;
+    }
+
+    @Override
+    public ServerHttpResponse getResponse() {
+        return responseDecorator;
+    }
+
+}

+ 29 - 0
src/main/java/com/dk/gateway/decorator/RequestParamsHandle.java

@@ -0,0 +1,29 @@
+package com.dk.gateway.decorator;
+
+import org.slf4j.Logger;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+
+
+/**
+ * @desc   : 请求参数处理类
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:08
+ */
+public class RequestParamsHandle {
+
+    //返回了一个dataBuffer,用作向下传递,否则dataBuffer被读取过一次后就不能继续使用了。
+    public static <T extends DataBuffer> T chain(ServerHttpRequest delegate, Logger log, T buffer) {
+        ParamsUtils.BodyDecorator bodyDecorator = ParamsUtils.buildBodyDecorator(buffer);
+        log.info("gateway-url: {}",delegate.getURI());
+        log.info("gateway-header: {}",delegate.getHeaders());
+        log.info("gateway-method: {}",delegate.getMethod());
+        log.info("gateway-queryParams: {}",delegate.getQueryParams());
+        //获取请求体
+        String body = bodyDecorator.getBody();
+        //如果是文件则不打印
+        log.info("gateway-requestBody: {}", body.contains("Content-Disposition:")?"[文件]":body);
+        return (T) bodyDecorator.getDataBuffer();
+    }
+
+}

+ 21 - 0
src/main/java/com/dk/gateway/decorator/ResponseParamsHandle.java

@@ -0,0 +1,21 @@
+package com.dk.gateway.decorator;
+
+import org.slf4j.Logger;
+import org.springframework.core.io.buffer.DataBuffer;
+
+/**
+ * @desc   : 响应参数处理类
+ * @author : 张潇木
+ * @date   : 2022-6-8 17:09
+ */
+public class ResponseParamsHandle {
+
+    public static <T extends DataBuffer> T chain(Logger log, T buffer) {
+        ParamsUtils.BodyDecorator bodyDecorator = ParamsUtils.buildBodyDecorator(buffer);
+        //响应打印
+        log.info("gateway-response: {}", bodyDecorator.getBody());
+        return (T) bodyDecorator.getDataBuffer();
+    }
+
+
+}

+ 29 - 0
src/main/java/com/dk/gateway/enums/ErrorCodeEnum.java

@@ -0,0 +1,29 @@
+package com.dk.gateway.enums;
+
+/**
+ * @author H_x_d
+ * 错误信息
+ * @date_time 2021-12-22 17:15
+ */
+public enum ErrorCodeEnum {
+    USER_TOKEN_EXPIRE(1002, "当前用户在其他设备上登录,此客户端已退出登录。"),
+
+    ;
+
+    private int code;
+    private String message;
+
+    ErrorCodeEnum(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}
+

+ 11 - 0
src/main/java/com/dk/gateway/oauth/exception/UnAuthorizedException.java

@@ -0,0 +1,11 @@
+package com.dk.gateway.oauth.exception;
+
+/**
+ * 未认证异常
+ */
+public class UnAuthorizedException extends RuntimeException {
+
+    public UnAuthorizedException(Throwable throwable) {
+        super(throwable);
+    }
+}

+ 194 - 0
src/main/java/com/dk/gateway/oauth/filter/Oauth2Filter.java

@@ -0,0 +1,194 @@
+package com.dk.gateway.oauth.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.dk.gateway.enums.ErrorCodeEnum;
+import com.dk.gateway.oauth.util.AESSecurityUtil;
+import com.dk.gateway.oauth.util.JwtUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Map;
+
+@Slf4j
+@Component
+public class Oauth2Filter implements GlobalFilter, Ordered {
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    // token校验跳过的url,多个url用";"号隔开
+    @Value("${filterPath}")
+    private String filterPath;
+    @Value("${mdmFilterPath}")
+    private String mdmFilterPath;
+    @Value("${aes-key}")
+    private String AESKey;
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        ServerHttpResponse response = exchange.getResponse();
+        // 过滤掉不需要进行权限控制的服务
+        String path = exchange.getRequest().getPath().toString();
+        logger.info("-------请求地址----{}", path);
+        String[] filterPaths = filterPath.split(";");
+        if (Arrays.asList(filterPaths).contains(path)) {
+            logger.info("------不需要权限----{}", path);
+            return chain.filter(exchange);
+        }
+        if (path.contains("/wxapi")) {
+            logger.info("------小程序接口----{}", path);
+            return chain.filter(exchange);
+        }
+        if (path.contains("/druid")) {
+            logger.info("------druid接口----{}", path);
+            return chain.filter(exchange);
+        }
+        if (path.contains("/scheduler-server")) {
+            logger.info("------定时任务接口----{}", path);
+            return chain.filter(exchange);
+        }
+        if (path.contains("/export")) {
+            logger.info("------export接口----{}" + path);
+            return chain.filter(exchange);
+        }
+        //todo
+        String[] mdmFilterPaths = mdmFilterPath.split(";");
+        if(mdmFilterPaths != null && mdmFilterPaths.length > 0 && path != null ){
+            String tempPath = path.substring(1);
+            tempPath = tempPath.substring(tempPath.indexOf("/"));
+            if (Arrays.asList(mdmFilterPaths).contains(tempPath)) {
+                logger.info("------不需要权限----{}", path);
+                return chain.filter(exchange);
+            }
+        }
+        // 获取token
+        String accessToken = exchange.getRequest().getHeaders().getFirst("Authorization");
+        String decodedAccessToken = accessToken;
+        logger.info("------获取的token----{}", decodedAccessToken);
+
+        if (accessToken != null) {
+            String[] tokens = accessToken.split(" ");
+            try {
+                String decrypt = AESSecurityUtil.decrypt(AESKey, tokens[1]);
+                String userId = JwtUtil.getUserId(decrypt);
+                String appCode = JwtUtil.getAppCode(decrypt);
+                String mapJson = stringRedisTemplate.opsForValue().get("REDIS_USER_LOGIN_" + userId + "_" + appCode);
+                Map<String, Object> userMap = JSON.parseObject(mapJson);
+                String token = "Bearer " + userMap.get("accessToken");
+                if (!accessToken.equals(token) ) {
+                    //定义响应体
+                    JSONObject result = new JSONObject() {{
+                        put("code", ErrorCodeEnum.USER_TOKEN_EXPIRE.getCode());
+                        put("message", ErrorCodeEnum.USER_TOKEN_EXPIRE.getMessage());
+                        put("data", "");
+                    }};
+                    //作JSON转换
+                    byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
+                    //调用bufferFactory方法,生成DataBuffer对象
+                    DataBuffer buffer = response.bufferFactory().wrap(bytes);
+                    //调用Mono中的just方法,返回要写给前端的JSON数据
+                    return response.writeWith(Mono.just(buffer));
+                }
+            } catch (Exception e) {
+                return chain.filter(exchange);
+            }
+        }
+
+        String jwt = null;
+        String userName = null;
+
+//        if (StringUtils.isNotBlank(decodedAccessToken)) {
+//            String[] tokens = decodedAccessToken.split(" ");
+//            // 验证Access Token
+//            logger.info("encode token ------->>>>{}", tokens[1]);
+//            try {
+//                // TOKEN反解密
+//                jwt = AESSecurityUtil.decrypt(AESKey, tokens[1]);
+//                decodedAccessToken = tokens[0] + " " + jwt;
+//                logger.info("decode Token: {}", decodedAccessToken);
+//            } catch (Exception e) {
+//                logger.error("error message: {}", e.getMessage());
+//                logger.error("sorry,accessToken({}),decode faild!", tokens[1]);
+//            }
+//            // 判断
+//            if (StringUtils.isBlank(jwt)) {
+//                logger.error("JWT 变量为空.");
+//            } else {
+//                userName = JwtUtil.getUserName(jwt);
+//            }
+//            // TOKEN校验
+//            if (!JwtUtil.verify(jwt, userName)) {
+//                // 如果不存在/过期了,返回未验证错误,需重新验证
+//                logger.info("------token过期----{}" , decodedAccessToken);
+//                // 定义响应头部信息
+//                response.setStatusCode(HttpStatus.UNAUTHORIZED);
+//                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+//
+//                //定义响应体
+//                JSONObject result = new JSONObject(){{
+//                    put("code",1002);
+//                    put("message","用户令牌已过期,请重新登录");
+//                    put("data","");
+//                }};
+//
+//                //作JSON转换
+//                byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
+//
+//                //调用bufferFactory方法,生成DataBuffer对象
+//                DataBuffer buffer = response.bufferFactory().wrap(bytes);
+//
+//                //调用Mono中的just方法,返回要写给前端的JSON数据
+//                return response.writeWith(Mono.just(buffer));
+//            }
+//        } else {
+//            logger.info("------token为空----{}" , decodedAccessToken);
+//            // 定义响应头部信息
+//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
+//            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+//
+//            //定义响应体
+//            JSONObject result = new JSONObject(){{
+//                put("code",1000);
+//                put("message","用户令牌为空,请重新登录");
+//                put("data","");
+//            }};
+//
+//            //作JSON转换
+//            byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
+//
+//            //调用bufferFactory方法,生成DataBuffer对象
+//            DataBuffer buffer = response.bufferFactory().wrap(bytes);
+//
+//            //调用Mono中的just方法,返回要写给前端的JSON数据
+//            return response.writeWith(Mono.just(buffer));
+//        }
+        return chain.filter(exchange);
+    }
+
+}

+ 69 - 0
src/main/java/com/dk/gateway/oauth/util/AESSecurityUtil.java

@@ -0,0 +1,69 @@
+package com.dk.gateway.oauth.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.Key;
+import java.util.Base64;
+import java.util.UUID;
+
+/**
+ * AES加密算法工具
+ */
+public class AESSecurityUtil {
+
+    /**
+     * 指定加密算法为AES
+     */
+    private static final String ALGORITHM = "AES";
+
+    /**
+     * 用来进行加密的操作
+     *
+     * @param data
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String keyString, String data)
+            throws Exception {
+        Key key = generateKey(keyString);
+        Cipher c = Cipher.getInstance(ALGORITHM);
+        c.init(Cipher.ENCRYPT_MODE, key);
+        byte[] encVal = c.doFinal(data.getBytes());
+        String encryptedValue = Base64.getEncoder().encodeToString(encVal);
+        return encryptedValue;
+    }
+
+    /**
+     * 用来进行解密的操作
+     *
+     * @param encryptedData
+     * @return
+     * @throws Exception
+     */
+    public static String decrypt(String keyString, String encryptedData) throws Exception {
+        Key key = generateKey(keyString);
+        Cipher c = Cipher.getInstance(ALGORITHM);
+        c.init(Cipher.DECRYPT_MODE, key);
+        byte[] decordedValue = Base64.getDecoder().decode(encryptedData);
+        byte[] decValue = c.doFinal(decordedValue);
+        String decryptedValue = new String(decValue);
+        return decryptedValue;
+    }
+
+    public static String generateKeyString() {
+        //必须长度为16
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
+    }
+
+    /**
+     * 根据密钥和算法生成Key
+     *
+     * @return
+     * @throws Exception
+     */
+    private static Key generateKey(String keyString) throws Exception {
+        Key key = new SecretKeySpec(keyString.getBytes(), ALGORITHM);
+        return key;
+    }
+
+}

+ 133 - 0
src/main/java/com/dk/gateway/oauth/util/JwtUtil.java

@@ -0,0 +1,133 @@
+package com.dk.gateway.oauth.util;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTDecodeException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class JwtUtil {
+    public static final String SHIRO_CP_ID = "cpId";
+    public static final String SHIRO_CP_CODE = "cpCode";
+    public static final String SHIRO_USER_NAME = "username";
+    public static final String SHIRO_USER_ID = "userId";
+    public static final String SHIRO_APP_CODE = "appCode";
+    public static final String SHIRO_CLIENT_ID = "clientId";
+    public static final String SHIRO_USER_SALT = "salt";
+    public static final String SHIRO_ISSUER = "Issuer";
+    public static final String SHIRO_SUBJECT = "long_token";
+    public static final String SHIRO_GRANT_TYPE = "grantType";
+
+    /**
+     * 校验token是否正确
+     *
+     * @param token 密钥
+     * @param salt  盐值
+     * @return 是否正确
+     */
+    public static boolean verify(String token, String salt) {
+        try {
+            Algorithm algorithm = Algorithm.HMAC256(salt);
+            JWTVerifier verifier = JWT.require(algorithm)
+                    //让token可以早生效30秒,避免服务器时间不一致导致校验不通过
+                    .acceptLeeway(30)
+                    // 签发人
+                    .withIssuer(SHIRO_ISSUER)
+                    // 主题
+                    .withSubject(SHIRO_SUBJECT)
+                    // 签发的目标
+                    //.withAudience(jwtProperties.getAudience())
+                    .build();
+            DecodedJWT jwt = verifier.verify(token);
+            if (jwt != null) {
+                return true;
+            }
+        } catch (Exception e) {
+            log.error("The token is invalid{}", e.getMessage());
+        }
+        return false;
+    }
+
+    /**
+     * 获得token中的信息无需secret解密也能获得
+     *
+     * @return token中包含的用户名
+     */
+    public static String getUserName(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_USER_NAME).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    public static String getUserId(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_USER_ID).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    public static String getCpId(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_CP_ID).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    public static String getAppCode(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_APP_CODE).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    public static String getCpCode(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_CP_CODE).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    public static String getGrantType(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim(SHIRO_GRANT_TYPE).asString();
+        } catch (JWTDecodeException e) {
+            log.error("error:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 解析token,获取token数据
+     *
+     * @param token
+     * @return
+     */
+    public static DecodedJWT getJwtInfo(String token) {
+        return JWT.decode(token);
+    }
+
+    public static String uuid32() {
+        return java.util.UUID.randomUUID().toString().replace("-", "");
+    }
+
+
+}

+ 89 - 0
src/main/resources/dev/bootstrap.yml

@@ -0,0 +1,89 @@
+server:
+  port: 8001
+spring:
+  application:
+    name: gateway-server
+  cloud:
+    gateway:
+      globalcors: #全局跨域设置,不需要再在controller上增加CrossOrigin注解
+        add-to-simple-url-handler-mapping: true
+        cors-configurations:
+          '[/**]':
+            allowedOrigins: "*"
+            allowedMethods: "*"
+            allowedHeaders: "*"
+            allowCredentials: true
+            maxAge: 360000
+      default-filters: #去除响应头中的多个 Access-Control-Allow-Origin,保留第一个
+        - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
+      routes:
+        #自定义路由,谁在前面谁优先。控制走本地服务 还是云服务。
+
+        #下方为例子,如果想调试,某一个服务,比如用户服务,那么先打开本地的用户服务,修改spring.application.name,
+        #再在本地启动用户服务,这时可以看到nacos上有2个用户服务,一个是云端的,一个是我们本地启动的。
+        #因为谁在前面谁优先,所以再次通过gateway调用用户服务时,会走我们本地的服务
+
+        #        - id: user-server
+        #          uri: lb://user-server-zxm
+        #          predicates:
+        #            - Path=/user-server/**
+        #          filters:
+        #            - StripPrefix=1
+        #还有一种情况就是你要临时调一下别人本地的服务,理论上将uri改成http://别人的内网ip+端口就可以,这个需要再测试。
+
+        #基础数据服务
+        - id: mdm-server
+          uri: lb://mdm-server
+          predicates:
+            - Path=/mdm-server/**
+          filters:
+            - StripPrefix=1
+
+    nacos:
+      config:
+        server-addr: 124.71.26.125:8848
+      discovery:
+        server-addr: 124.71.26.125:8848
+        namespace: dkic_m-dev
+  #    sentinel:
+  #      transport:
+  #        dashboard: s.dev01.dkiboss.com:7019
+  redis:
+    host: s.dev01.dkiboss.com
+    port: 14000
+    password: dk
+
+  zipkin:
+    base-url: http://s.dev01.dkiboss.com:9411/
+    discovery-client-enabled: false
+  sleuth:
+    sampler:
+      probability: 1
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 10MB
+
+logback:
+  file: D:\DK_IBOSS_MINI\${spring.application.name}
+
+ribbon:
+  ServerListRefreshInterval: 3000
+
+feign:
+  sentinel:
+    enabled: true
+  client:
+    config:
+      default:
+        connectTimeout: 60000
+        readTimeout: 60000
+
+aes-key: b6f64c1001b04b9f
+client-app-id: 48849faf-8bbb-4a29-9548-0ba1c3df963f
+
+# token校验跳过的url,多个url用";"号隔开
+filterPath: /oauth-server/oauth/token;/oauth-server/oauth/wx_token;/user-server/core/user/qv_scan_login;/basic-server/file/upload
+# token校验跳过的url,多个url用";"号隔开(由于mdm服务是动态的,需要单独设置)
+mdmFilterPath: /mst/staff/get_info_after_login
+

+ 191 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration  scan="true" scanPeriod="10 seconds">
+
+    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
+
+    <springProperty scope="context" name="log.path" source="logback.file" defaultValue="log"/>
+    <contextName>logback</contextName>
+    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
+    <!--<property name="log.path" value="E:/logsNew" />-->
+
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+
+    <!--输出到控制台-->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>info</level>
+        </filter>
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+
+    <!--输出到文件-->
+
+    <!-- 时间滚动输出 level为 DEBUG 日志 -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <!--<file>${log.path}/log_debug.log</file>-->
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志归档 -->
+            <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>debug</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 时间滚动输出 level为 INFO 日志 -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <!--<file>${log.path}/log_info.log</file>-->
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 每天日志归档路径以及格式 -->
+            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>info</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 时间滚动输出 level为 WARN 日志 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <!--<file>${log.path}/log_warn.log</file>-->
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>warn</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <!--<file>${log.path}/log_error.log</file>-->
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录ERROR级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--
+        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
+        以及指定<appender>。<logger>仅有一个name属性,
+        一个可选的level和一个可选的addtivity属性。
+        name:用来指定受此logger约束的某一个包或者具体的某一个类。
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+              还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
+              如果未设置此属性,那么当前logger将会继承上级的级别。
+        addtivity:是否向上级logger传递打印信息。默认是true。
+    -->
+    <logger name="org.springframework.web" level="info"/>
+    <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
+    <!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
+        第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
+        第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: -->
+
+    <!-- mybatis日志打印-->
+    <!--<logger name="org.apache.ibatis" level="DEBUG" />-->
+    <!--<logger name="java.sql" level="DEBUG" />-->
+    <!--<logger name="com.dongke.hn.dao.mapper" level="DEBUG"></logger>-->
+
+
+    <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+        不能设置为INHERITED或者同义词NULL。默认是DEBUG
+        可以包含零个或多个元素,标识这个appender将会添加到这个logger。 -->
+
+    <!--开发环境:打印控制台-->
+    <springProfile name="dev">
+        <logger name="com.sfDev.view" level="debug"/>
+    </springProfile>
+
+    <root level="info">
+        <appender-ref ref="CONSOLE" />
+        <appender-ref ref="DEBUG_FILE" />
+        <appender-ref ref="INFO_FILE" />
+        <appender-ref ref="WARN_FILE" />
+        <appender-ref ref="ERROR_FILE" />
+    </root>
+
+    <!--生产环境:输出到文件-->
+    <springProfile name="pro">
+        <root level="info">
+            <appender-ref ref="CONSOLE" />
+            <appender-ref ref="DEBUG_FILE" />
+            <appender-ref ref="INFO_FILE" />
+            <appender-ref ref="ERROR_FILE" />
+            <appender-ref ref="WARN_FILE" />
+        </root>
+    </springProfile>
+
+</configuration>

+ 18 - 0
src/main/resources/prod/bootstrap.yml

@@ -0,0 +1,18 @@
+server:
+  port: 6001
+spring:
+  application:
+    name: gateway-server
+  cloud:
+    nacos:
+      config:
+        file-extension: yaml
+        server-addr: ${NACOS_HOST:mse-ab4cb036-nacos-ans.mse.aliyuncs.com:8848}
+        namespace: ${NACOS_SPACE:hgscrm-prod}
+        shared-configs:
+          - data-id: common.yaml
+            group: DEFAULT_GROUP
+        group: ${group-id:DEFAULT_GROUP}
+      discovery:
+        server-addr: ${NACOS_HOST:mse-ab4cb036-nacos-ans.mse.aliyuncs.com:8848}
+        namespace: ${NACOS_SPACE:hgscrm-prod}

+ 70 - 0
src/main/resources/st/bootstrap.yml

@@ -0,0 +1,70 @@
+server:
+  port: 6001
+spring:
+  application:
+    name: gateway-server
+  cloud:
+    gateway:
+      globalcors: #全局跨域设置,不需要再在controller上增加CrossOrigin注解
+        add-to-simple-url-handler-mapping: true
+        cors-configurations:
+          '[/**]':
+            allowedOrigins: "*"
+            allowedMethods: "*"
+            allowedHeaders: "*"
+            allowCredentials: true
+            maxAge: 360000
+      default-filters: #去除响应头中的多个 Access-Control-Allow-Origin,保留第一个
+        - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
+      discovery:
+        locator:
+          enabled: true #开启gateway从nacos上获取服务列表,id就是服务名。注意,此方式的优先级比自定义routes的方式高。开发时不要开启
+    nacos:
+      config:
+        server-addr: 192.168.0.90:8848
+      discovery:
+        server-addr: 192.168.0.90:8848
+        ip: 192.168.0.90 #默认是局域网ip,固定为外网ip
+        namespace: iboss-dev
+  #    sentinel:
+  #      transport:
+  #        dashboard: s.dev01.dkiboss.com:7019
+  redis:
+    host: s.dev01.dkiboss.com
+    port: 14000
+    password: dk
+
+  zipkin:
+    base-url: http://s.dev01.dkiboss.com:9411/
+    discovery-client-enabled: false
+  sleuth:
+    sampler:
+      probability: 1
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 10MB
+
+logback:
+  file: /home/java_project/dk_mes/${spring.application.name}/${spring.application.name}_logs
+
+ribbon:
+  ServerListRefreshInterval: 3000
+
+feign:
+  sentinel:
+    enabled: true
+  client:
+    config:
+      default:
+        connectTimeout: 60000
+        readTimeout: 60000
+
+aes-key: b6f64c1001b04b9f
+client-app-id: 48849faf-8bbb-4a29-9548-0ba1c3df963f
+
+# token校验跳过的url,多个url用";"号隔开
+filterPath: /oauth-server/oauth/token;/oauth-server/oauth/wx_token;/user-server/core/user/qv_scan_login;/basic-server/file/upload
+# token校验跳过的url,多个url用";"号隔开(由于mdm服务是动态的,需要单独设置)
+mdmFilterPath: /mst/staff/get_info_after_login
+

+ 69 - 0
src/main/resources/test/bootstrap.yml

@@ -0,0 +1,69 @@
+server:
+  port: 7001
+spring:
+  application:
+    name: gateway-server
+  cloud:
+    gateway:
+      globalcors: #全局跨域设置,不需要再在controller上增加CrossOrigin注解
+        add-to-simple-url-handler-mapping: true
+        cors-configurations:
+          '[/**]':
+            allowedOrigins: "*"
+            allowedMethods: "*"
+            allowedHeaders: "*"
+            allowCredentials: true
+            maxAge: 360000
+      default-filters: #去除响应头中的多个 Access-Control-Allow-Origin,保留第一个
+        - DedupeResponseHeader=Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
+      discovery:
+        locator:
+          enabled: true #开启gateway从nacos上获取服务列表,id就是服务名。注意,此方式的优先级比自定义routes的方式高。开发时不要开启
+    nacos:
+      config:
+        server-addr: 124.71.26.125:8848
+      discovery:
+        server-addr: 124.71.26.125:8848
+        ip: 124.71.26.125 #默认是局域网ip,固定为外网ip
+        namespace: iboss-dev
+  #    sentinel:
+  #      transport:
+  #        dashboard: s.dev01.dkiboss.com:7019
+  redis:
+    host: s.dev01.dkiboss.com
+    port: 14000
+    password: dk
+
+  zipkin:
+    base-url: http://s.dev01.dkiboss.com:9411/
+    discovery-client-enabled: false
+  sleuth:
+    sampler:
+      probability: 1
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 10MB
+
+logback:
+  file: /data/java_project/dkic/${spring.application.name}/${spring.application.name}_logs
+
+ribbon:
+  ServerListRefreshInterval: 3000
+
+feign:
+  sentinel:
+    enabled: true
+  client:
+    config:
+      default:
+        connectTimeout: 60000
+        readTimeout: 60000
+
+aes-key: b6f64c1001b04b9f
+client-app-id: 48849faf-8bbb-4a29-9548-0ba1c3df963f
+
+# token校验跳过的url,多个url用";"号隔开
+filterPath: /oauth-server/oauth/token;/oauth-server/oauth/wx_token;/user-server/core/user/qv_scan_login;/basic-server/file/upload
+# token校验跳过的url,多个url用";"号隔开(由于mdm服务是动态的,需要单独设置)
+mdmFilterPath: /mst/staff/get_info_after_login

+ 18 - 0
src/main/resources/uat/bootstrap.yml

@@ -0,0 +1,18 @@
+server:
+  port: 6001
+spring:
+  application:
+    name: gateway-server
+  cloud:
+    nacos:
+      config:
+        file-extension: yaml
+        server-addr: ${NACOS_HOST:mse-ab4cb036-nacos-ans.mse.aliyuncs.com:8848}
+        namespace: ${NACOS_SPACE:hgscrm-uat}
+        shared-configs:
+          - data-id: common.yaml
+            group: DEFAULT_GROUP
+        group: ${group-id:DEFAULT_GROUP}
+      discovery:
+        server-addr: ${NACOS_HOST:mse-ab4cb036-nacos-ans.mse.aliyuncs.com:8848}
+        namespace: ${NACOS_SPACE:hgscrm-uat}