gateway
This commit is contained in:
48
.gitignore
vendored
48
.gitignore
vendored
@@ -1,23 +1,33 @@
|
|||||||
# Compiled class file
|
HELP.md
|
||||||
*.class
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
# Log file
|
### STS ###
|
||||||
*.log
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
# BlueJ files
|
### IntelliJ IDEA ###
|
||||||
*.ctxt
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
# Mobile Tools for Java (J2ME)
|
### NetBeans ###
|
||||||
.mtj.tmp/
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
# Package Files #
|
### VS Code ###
|
||||||
*.jar
|
.vscode/
|
||||||
*.war
|
|
||||||
*.nar
|
|
||||||
*.ear
|
|
||||||
*.zip
|
|
||||||
*.tar.gz
|
|
||||||
*.rar
|
|
||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
||||||
hs_err_pid*
|
|
||||||
|
|||||||
81
pom.xml
Normal file
81
pom.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.flagnote</groupId>
|
||||||
|
<artifactId>gateway</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>gateway</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>11</java.version>
|
||||||
|
<spring-cloud.version>2021.0.3</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.7.22</version>
|
||||||
|
</dependency>
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
12
src/main/java/com/flagnote/gateway/GatewayApplication.java
Normal file
12
src/main/java/com/flagnote/gateway/GatewayApplication.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package com.flagnote.gateway;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class GatewayApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(GatewayApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.flagnote.gateway.config;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ApiLimiterConfiguration {
|
||||||
|
|
||||||
|
@Bean(name="remoteSessionKeyResolver")
|
||||||
|
public KeyResolver remoteSessionKeyResolver() {
|
||||||
|
return exchange -> Mono.just(exchange.getSession().block().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name="noteKeyResolver")
|
||||||
|
public KeyResolver noteKeyResolver() {
|
||||||
|
return exchange -> Mono.just(exchange.getRequest().getPath().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Primary
|
||||||
|
@Bean(name="remoteAddrKeyResolver")
|
||||||
|
public KeyResolver remoteAddrKeyResolver() {
|
||||||
|
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.flagnote.gateway.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||||
|
import org.springframework.web.reactive.config.EnableWebFlux;
|
||||||
|
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebFlux
|
||||||
|
public class WebFluxWebConfig implements WebFluxConfigurer {
|
||||||
|
@Override
|
||||||
|
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||||
|
configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.flagnote.gateway.filter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
import com.flagnote.gateway.utils.BizKeyUtils;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSON;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ValidateNoteCipherFilter implements GatewayFilter, Ordered {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
|
||||||
|
String noteKey = uriVariables.get("key");
|
||||||
|
|
||||||
|
String requestBody = exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR);
|
||||||
|
JSONObject body = JSONUtil.parseObj(requestBody);
|
||||||
|
String cipher = body.getStr("cipher");
|
||||||
|
String key = body.getStr("key");
|
||||||
|
|
||||||
|
if (!noteKey.equals(key)) {
|
||||||
|
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
|
||||||
|
return exchange.getResponse().setComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BizKeyUtils.validateCipher(noteKey, cipher)) {
|
||||||
|
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
|
||||||
|
return exchange.getResponse().setComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先级: 数字越小优先级越高
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.flagnote.gateway.filter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
import com.flagnote.gateway.utils.BizKeyUtils;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局过滤器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ValidateNoteKeyFilter implements GatewayFilter, Ordered {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
|
||||||
|
|
||||||
|
String noteKey = uriVariables.get("key");
|
||||||
|
|
||||||
|
if (!BizKeyUtils.validateKey(noteKey)) {
|
||||||
|
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
|
||||||
|
return exchange.getResponse().setComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先级: 数字越小优先级越高
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.LOWEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.flagnote.gateway.filter.factory;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig;
|
||||||
|
import org.springframework.cloud.gateway.support.GatewayToStringStyler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
import com.flagnote.gateway.filter.ValidateNoteCipherFilter;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class ValidateNoteCipherGatewayFilterFactory
|
||||||
|
extends AbstractGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ValidateNoteCipherFilter validateNoteCipherFilter;
|
||||||
|
|
||||||
|
|
||||||
|
public ValidateNoteCipherGatewayFilterFactory() {
|
||||||
|
super(NameConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GatewayFilter apply(NameConfig config) {
|
||||||
|
|
||||||
|
return validateNoteCipherFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.flagnote.gateway.filter.factory;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig;
|
||||||
|
import org.springframework.cloud.gateway.support.GatewayToStringStyler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
import com.flagnote.gateway.filter.ValidateNoteKeyFilter;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class ValidateNoteKeyGatewayFilterFactory
|
||||||
|
extends AbstractGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ValidateNoteKeyFilter validateNoteKeyFilter;
|
||||||
|
|
||||||
|
|
||||||
|
public ValidateNoteKeyGatewayFilterFactory() {
|
||||||
|
super(NameConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public List<String> shortcutFieldOrder() {
|
||||||
|
// return Arrays.asList("name");
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GatewayFilter apply(NameConfig config) {
|
||||||
|
|
||||||
|
return validateNoteKeyFilter;
|
||||||
|
|
||||||
|
// return new GatewayFilter() {
|
||||||
|
// @Override
|
||||||
|
// public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
// // 获取请求路径
|
||||||
|
// URI uri = exchange.getRequest().getURI();
|
||||||
|
// log.info("获取到请求路径:{}", uri.toString());
|
||||||
|
// //
|
||||||
|
// log.info("配置属性:{}", config.getName());
|
||||||
|
// return chain.filter(exchange);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// return GatewayToStringStyler.filterToStringCreator(ValidateNoteKeyGatewayFilterFactory.this).toString();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//package com.flagnote.gateway.resolver;
|
||||||
|
//
|
||||||
|
//import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
//import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||||||
|
//import org.springframework.stereotype.Component;
|
||||||
|
//import org.springframework.web.server.ServerWebExchange;
|
||||||
|
//
|
||||||
|
//import reactor.core.publisher.Mono;
|
||||||
|
//
|
||||||
|
//@Component("remoteAddrKeyResolver")
|
||||||
|
//@Qualifier("remoteAddrKeyResolver")
|
||||||
|
//public class RemoteAddrKeyResolver implements KeyResolver {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Mono<String> resolve(ServerWebExchange exchange) {
|
||||||
|
// return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//package com.flagnote.gateway.resolver;
|
||||||
|
//
|
||||||
|
//import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
//import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||||||
|
//import org.springframework.stereotype.Component;
|
||||||
|
//import org.springframework.web.server.ServerWebExchange;
|
||||||
|
//
|
||||||
|
//import reactor.core.publisher.Mono;
|
||||||
|
//
|
||||||
|
//@Component("remoteSessionKeyResolver")
|
||||||
|
//@Qualifier("remoteSessionKeyResolver")
|
||||||
|
//public class RemoteSessionKeyResolver implements KeyResolver {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Mono<String> resolve(ServerWebExchange exchange) {
|
||||||
|
// return Mono.just(exchange.getSession().block().getId());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
100
src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java
Normal file
100
src/main/java/com/flagnote/gateway/utils/BizKeyUtils.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package com.flagnote.gateway.utils;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
|
public class BizKeyUtils {
|
||||||
|
|
||||||
|
public static final String MIX_STRING = "6v8muhqp8ta45ncsyi8y";
|
||||||
|
|
||||||
|
public static final String RANGE_STRING = "abcdefhikmnopqstuvwxyz23456789";
|
||||||
|
|
||||||
|
public static String getKey() {
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
for (int i = 0; i < 13; i++) {
|
||||||
|
sb.append(RANGE_STRING.charAt(RandomUtils.nextInt(30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(getFilteredKey(md5(sb.toString() + MIX_STRING + getPrefixTime())));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFilteredKey(String key) {
|
||||||
|
String result = "";
|
||||||
|
for (int i = 0; i < key.length(); i++) {
|
||||||
|
String ts = String.valueOf(key.charAt(i));
|
||||||
|
if (RANGE_STRING.indexOf(ts) >= 0) {
|
||||||
|
result += ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length() == 3) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < 3; i++) {
|
||||||
|
result += "x";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean validateKey(String key) {
|
||||||
|
String oKey = key.substring(0, 13);
|
||||||
|
|
||||||
|
String cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + getPrefixTime()));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() - 1)));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() + 1)));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String mixKey(String key) {
|
||||||
|
return md5(key + md5(MIX_STRING + key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String md5(String text) {
|
||||||
|
try {
|
||||||
|
return DigestUtils.md5DigestAsHex(text.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("无法生成MD5");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getPrefixTime() {
|
||||||
|
return Integer.parseInt(String.valueOf(new Date().getTime()).substring(0, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCipher(String key) {
|
||||||
|
return md5(key + MIX_STRING + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean validateCipher(String key,String cipher) {
|
||||||
|
return md5(key + MIX_STRING + key).equals(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getSecretKey(String key, String password) {
|
||||||
|
return md5(key + md5(MIX_STRING + password));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
src/main/java/com/flagnote/gateway/utils/RandomUtils.java
Normal file
15
src/main/java/com/flagnote/gateway/utils/RandomUtils.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.flagnote.gateway.utils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
public class RandomUtils {
|
||||||
|
|
||||||
|
|
||||||
|
public static ThreadLocalRandom getRandom() {
|
||||||
|
return ThreadLocalRandom.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer nextInt(Integer num) {
|
||||||
|
return getRandom().nextInt(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
143
src/main/resources/application.yml
Normal file
143
src/main/resources/application.yml
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
server:
|
||||||
|
port: 55555
|
||||||
|
spring:
|
||||||
|
codec:
|
||||||
|
max-in-memory-size: 100MB
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
# 最大支持文件大小
|
||||||
|
max-file-size: 100MB
|
||||||
|
# 最大支持请求大小
|
||||||
|
max-request-size: 100MB
|
||||||
|
redis:
|
||||||
|
host: cq.openif.com
|
||||||
|
port: 6379
|
||||||
|
timeout: 1000
|
||||||
|
poolMaxTotal: 10
|
||||||
|
poolMaxIdle: 10
|
||||||
|
poolMaxWait: 3
|
||||||
|
password: 1qazx1qazx
|
||||||
|
application:
|
||||||
|
name: gateway
|
||||||
|
cloud:
|
||||||
|
discovery:
|
||||||
|
client:
|
||||||
|
simple:
|
||||||
|
instances:
|
||||||
|
keyMetaService: # 一定要带端口
|
||||||
|
- uri: http://localhost:3333
|
||||||
|
# - uri: http://flagnote.com:3333
|
||||||
|
loadbalancer:
|
||||||
|
health-check:
|
||||||
|
# path:
|
||||||
|
# noteKey: /getHealth
|
||||||
|
initial-delay: 0 #运行状况检查计划程序的初始延迟值。
|
||||||
|
interval: 5s # 重新运行运行状况检查计划程序的时间间隔。
|
||||||
|
configurations: health-check #启用预定义的负载平衡器配置。
|
||||||
|
|
||||||
|
inetutils:
|
||||||
|
# 指定此客户端的ip
|
||||||
|
default-ip-address: localhost
|
||||||
|
gateway:
|
||||||
|
globalcors:
|
||||||
|
corsConfigurations:
|
||||||
|
'[/**]':
|
||||||
|
allowedOrigins: "*"
|
||||||
|
allowedMethods: "*"
|
||||||
|
routes:
|
||||||
|
- id: keyMeta
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/keyMeta
|
||||||
|
- Method=GET
|
||||||
|
filters:
|
||||||
|
- name: RequestRateLimiter
|
||||||
|
args:
|
||||||
|
# 如果返回的key是空的话,false则不进行限流
|
||||||
|
# deny-empty-key: true
|
||||||
|
# status-code: TOO_MANY_REQUESTS
|
||||||
|
# 每秒产生多少个令牌
|
||||||
|
redis-rate-limiter.replenishRate: 1
|
||||||
|
# 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求
|
||||||
|
redis-rate-limiter.burstCapacity: 1
|
||||||
|
# 每次请求申请几个令牌
|
||||||
|
redis-rate-limiter.requestedTokens: 1
|
||||||
|
# IP 地址限流
|
||||||
|
key-resolver: "#{@remoteAddrKeyResolver}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: RequestRateLimiter
|
||||||
|
args:
|
||||||
|
# 如果返回的key是空的话,false则不进行限流
|
||||||
|
# deny-empty-key: true
|
||||||
|
# status-code: TOO_MANY_REQUESTS
|
||||||
|
# 每秒产生多少个令牌
|
||||||
|
redis-rate-limiter.replenishRate: 1
|
||||||
|
# 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求
|
||||||
|
redis-rate-limiter.burstCapacity: 3
|
||||||
|
# 每次请求申请几个令牌
|
||||||
|
redis-rate-limiter.requestedTokens: 3
|
||||||
|
# IP 地址限流
|
||||||
|
key-resolver: "#{@remoteSessionKeyResolver}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- id: noteMeta
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/noteMeta
|
||||||
|
- Method=GET
|
||||||
|
filters:
|
||||||
|
- ValidateNoteKey
|
||||||
|
- id: getNote
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}
|
||||||
|
- Method=GET
|
||||||
|
filters:
|
||||||
|
- ValidateNoteKey
|
||||||
|
- id: saveNote
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}
|
||||||
|
- Method=POST
|
||||||
|
filters:
|
||||||
|
- name: ValidateNoteKey
|
||||||
|
- name: CacheRequestBody
|
||||||
|
args:
|
||||||
|
bodyClass: java.lang.String
|
||||||
|
- name: ValidateNoteCipher
|
||||||
|
- id: deleteNote
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/delete
|
||||||
|
- Method=POST
|
||||||
|
filters:
|
||||||
|
- ValidateNoteKey
|
||||||
|
- id: secretKey
|
||||||
|
uri: lb://keyMetaService
|
||||||
|
order: -1
|
||||||
|
predicates:
|
||||||
|
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/secretKey
|
||||||
|
- Method=POST
|
||||||
|
filters:
|
||||||
|
- ValidateNoteKey
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
org.springframework.cloud.gateway: trace
|
||||||
|
org.springframework.cloud.loadbalancer: trace
|
||||||
|
# org.springframework.web.reactive: trace
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.flagnote.gateway;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class GatewayApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user