Browse Source

重构国际化,权限开发,网关开发。

master
caojianbin 8 months ago
parent
commit
b5877f1329
  1. 4
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/EcellAuthApplication.java
  2. 9
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/config/ExceptionAdviceConfig.java
  3. 64
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/controller/AuthController.java
  4. 17
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/utils/AuthLogic.java
  5. 19
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/utils/AuthUtil.java
  6. 7
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/utils/locale/LocaleUtil.java
  7. 98
      ecell-internationalize/ecell-internationalize-gateway/pom.xml
  8. 14
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/EcellGatewayApplication.java
  9. 84
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/CaptchaConfig.java
  10. 72
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/GatewayConfig.java
  11. 73
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/KaptchaTextCreator.java
  12. 43
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/properties/CaptchaProperties.java
  13. 31
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/properties/IgnoreWhiteProperties.java
  14. 109
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/constant/MessagesConstant.java
  15. 99
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/constant/RateLimitInfo.java
  16. 211
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/AuthFilter.java
  17. 57
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/BlackListUrlFilter.java
  18. 86
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/CacheRequestFilter.java
  19. 58
      ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/handler/GatewayExceptionHandler.java
  20. 74
      ecell-internationalize/ecell-internationalize-gateway/src/main/resources/application-dev.yml
  21. 40
      ecell-internationalize/ecell-internationalize-gateway/src/main/resources/bootstrap.yml
  22. 15
      ecell-internationalize/ecell-internationalize-gateway/src/main/resources/lua/rateLimit.lua

4
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/EcellAuthApplication.java

@ -1,13 +1,9 @@ @@ -1,13 +1,9 @@
package com.ecell.internationalize.auth;
import com.ecell.internationalize.auth.config.ExceptionAdviceConfig;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author borui

9
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/config/ExceptionAdviceConfig.java

@ -28,13 +28,6 @@ public class ExceptionAdviceConfig { @@ -28,13 +28,6 @@ public class ExceptionAdviceConfig {
@ExceptionHandler(Exception.class)
public AjaxResult exceptionHandler(Exception e) {
e.printStackTrace();
// Locale locale = LocaleUtil.getLocale();
//
// MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
// String message = messageSource.getMessage("messages.login.empty", null, locale);
String message = LocaleUtil.getMessage("messages.login.empty");
System.out.println("获取到的国际化语言是:=="+message);
return AjaxResult.error(message);
return AjaxResult.error(LocaleUtil.getMessage("messages.error"));
}
}

64
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/controller/AuthController.java

@ -1,8 +1,20 @@ @@ -1,8 +1,20 @@
package com.ecell.internationalize.auth.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ecell.internationalize.auth.entity.UserType;
import com.ecell.internationalize.auth.feign.SysUserFeignClient;
import com.ecell.internationalize.auth.service.SysUserLoginService;
import com.ecell.internationalize.auth.utils.AuthUtil;
import com.ecell.internationalize.common.core.domain.UserLogin;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.core.utils.locale.LocaleUtil;
import com.ecell.internationalize.common.core.web.domain.AjaxResult;
import com.ecell.internationalize.common.core.web.domain.R;
import com.ecell.internationalize.common.security.service.TokenService;
import com.ecell.internationalize.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @author borui
@ -10,11 +22,49 @@ import org.springframework.web.bind.annotation.RestController; @@ -10,11 +22,49 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/auth")
public class AuthController {
private final Integer FAIL_CODE = 500;
@Autowired
private TokenService tokenServiceImpl;
@Autowired
private SysUserLoginService sysUserLoginService;
@Autowired
private SysUserFeignClient sysUserFeignClient;
@PostMapping("login")
public AjaxResult login(@RequestBody UserType userType) {
// 用户登录校验
R<UserLogin> userLogin = sysUserLoginService.login(userType.getUsername(), userType.getPassword());
if (FAIL_CODE == userLogin.getCode()) {
return AjaxResult.error(userLogin.getMsg());
}
// 获取登录token
return AjaxResult.success(LocaleUtil.getMessage("messages.success"), tokenServiceImpl.createToken(userLogin.getData()));
}
@DeleteMapping("logout")
public AjaxResult logout(HttpServletRequest request) {
String token = SecurityUtils.getToken(request);
if (StringUtils.isNotEmpty(token)) {
// 删除用户缓存记录
AuthUtil.logoutByToken(token);
}
return AjaxResult.success(LocaleUtil.getMessage("messages.success"));
}
@PostMapping("refresh")
public AjaxResult refresh(HttpServletRequest request) {
UserLogin userLogin = tokenServiceImpl.getUserLogin(request);
if (StringUtils.isNotNull(userLogin)) {
// 刷新令牌有效期
tokenServiceImpl.refreshToken(userLogin);
return AjaxResult.success(LocaleUtil.getMessage("messages.success"));
}
return AjaxResult.success(LocaleUtil.getMessage("messages.success"));
}
@GetMapping("test")
public String test( ){
int a=1;
int b= a/0;
return "111";
public UserLogin test(String userName) {
return sysUserFeignClient.queryByUser(userName);
}
}

17
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/utils/AuthLogic.java

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package com.ecell.internationalize.auth.utils;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.security.service.TokenService;
/**
* @author borui
*/
public class AuthLogic {
public TokenService tokenServiceImpl = SpringUtils.getBean(TokenService.class);
/**
* 会话注销根据指定Token
*/
public void logoutByToken(String token) {
tokenServiceImpl.delLoginUser(token);
}
}

19
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/utils/AuthUtil.java

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
package com.ecell.internationalize.auth.utils;
/**
* @author borui
*/
public class AuthUtil {
/**
* 底层的 AuthLogic 对象
*/
public static AuthLogic authLogic = new AuthLogic();
/**
* 会话注销根据指定Token
*
* @param token 指定token
*/
public static void logoutByToken(String token) {
authLogic.logoutByToken(token);
}
}

7
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/utils/locale/LocaleUtil.java

@ -13,7 +13,7 @@ import java.util.Locale; @@ -13,7 +13,7 @@ import java.util.Locale;
*/
public class LocaleUtil {
public static Locale getLocale(){
public static Locale getLocale() {
String language = ServletUtils.getHeader(ServletUtils.getRequest(), "content-language");
Locale locale;
@ -21,7 +21,7 @@ public class LocaleUtil { @@ -21,7 +21,7 @@ public class LocaleUtil {
locale = Locale.US;
} else {
try {
String [] split = language.split("_");
String[] split = language.split("_");
locale = new Locale(split[0], split[1]);
} catch (Exception e) {
locale = Locale.US;
@ -31,8 +31,7 @@ public class LocaleUtil { @@ -31,8 +31,7 @@ public class LocaleUtil {
}
public static String getMessage(String code) {
Locale locale = getLocale();
return SpringUtils.getBean(MessageSource.class).getMessage(code, null, locale);
return SpringUtils.getBean(MessageSource.class).getMessage(code, null, getLocale());
}

98
ecell-internationalize/ecell-internationalize-gateway/pom.xml

@ -12,9 +12,99 @@ @@ -12,9 +12,99 @@
<groupId>com.ecell.internationalize.gateway</groupId>
<artifactId>ecell-internationalize-gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- SpringCloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel Datasource Nacos -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
</dependency>
<!-- RuoYi Common Redis-->
<dependency>
<groupId>com.ecell.internationalize.common.redis</groupId>
<artifactId>ecell-internationalize-redis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

14
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/EcellGatewayApplication.java

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
package com.ecell.internationalize.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class EcellGatewayApplication {
public static void main(String[] args)
{
SpringApplication.run(EcellGatewayApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 易赛网关启动成功 ლ(´ڡ`ლ)゙");
}
}

84
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/CaptchaConfig.java

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
package com.ecell.internationalize.gateway.config;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @author borui
*/
@Configuration
public class CaptchaConfig {
@Bean(name = "captchaProducer")
public DefaultKaptcha getKaptchaBean()
{
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yes,no
properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// 验证码文本字符颜色 默认为Color.BLACK
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 验证码图片宽度 默认为200
properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "160");
// 验证码图片高度 默认为50
properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "60");
// 验证码文本字符大小 默认为40
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// KAPTCHA_SESSION_KEY
properties.setProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 验证码文本字符长度 默认为5
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
@Bean(name = "captchaProducerMath")
public DefaultKaptcha getKaptchaBeanMath()
{
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有边框 默认为true 我们可以自己设置yes,no
properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// 边框颜色 默认为Color.BLACK
properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "105,179,90");
// 验证码文本字符颜色 默认为Color.BLACK
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
// 验证码图片宽度 默认为200
properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "160");
// 验证码图片高度 默认为50
properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "60");
// 验证码文本字符大小 默认为40
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
// KAPTCHA_SESSION_KEY
properties.setProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
// 验证码文本生成器
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator");
// 验证码文本字符间距 默认为2
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
// 验证码文本字符长度 默认为5
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 验证码噪点颜色 默认为Color.BLACK
properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "white");
// 干扰实现类
properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}

72
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/GatewayConfig.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
package com.ecell.internationalize.gateway.config;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayParamFlowItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.ecell.internationalize.gateway.handler.SentinelFallbackHandler;
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.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import java.util.HashSet;
import java.util.Set;
/**
* @author borui
*/
@Configuration
public class GatewayConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler()
{
return new SentinelFallbackHandler();
}
/**
*
* 初始化限流规则
* */
// @PostConstruct
public void doInit(){
initGatewayRules();
}
/**
* 硬编码网关限流规则
*/
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
GatewayFlowRule rule = new GatewayFlowRule();
// 指定限流模式, 根据 route_id 做限流, 默认的模式
rule.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID);
// 指定 route_id -> service id
rule.setResource("yisai-system");
GatewayParamFlowItem paramItem = new GatewayParamFlowItem();
paramItem.setFieldName("appId");
rule.setParamItem(paramItem);
// 按照 QPS 限流
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 统计窗口和限流阈值
rule.setIntervalSec(60);
rule.setCount(3);
rules.add(rule);
// 加载到网关中
GatewayRuleManager.loadRules(rules);
}
@Bean
public DefaultRedisScript<Long> limitScript(){
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setResultType(Long.class);
script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua\\rateLimit.lua")));
return script;
}
}

73
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/KaptchaTextCreator.java

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
package com.ecell.internationalize.gateway.config;
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
import java.util.Random;
/**
* @author borui
*/
public class KaptchaTextCreator extends DefaultTextCreator {
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
@Override
public String getText()
{
Integer result = 0;
Random random = new Random();
int x = random.nextInt(10);
int y = random.nextInt(10);
StringBuilder suChinese = new StringBuilder();
int randomoperands = (int) Math.round(Math.random() * 2);
if (randomoperands == 0)
{
result = x * y;
suChinese.append(CNUMBERS[x]);
suChinese.append("*");
suChinese.append(CNUMBERS[y]);
}
else if (randomoperands == 1)
{
if (!(x == 0) && y % x == 0)
{
result = y / x;
suChinese.append(CNUMBERS[y]);
suChinese.append("/");
suChinese.append(CNUMBERS[x]);
}
else
{
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
}
else if (randomoperands == 2)
{
if (x >= y)
{
result = x - y;
suChinese.append(CNUMBERS[x]);
suChinese.append("-");
suChinese.append(CNUMBERS[y]);
}
else
{
result = y - x;
suChinese.append(CNUMBERS[y]);
suChinese.append("-");
suChinese.append(CNUMBERS[x]);
}
}
else
{
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
suChinese.append("=?@" + result);
return suChinese.toString();
}
}

43
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/properties/CaptchaProperties.java

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
package com.ecell.internationalize.gateway.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
* @author borui
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.captcha")
public class CaptchaProperties {
/**
* 验证码开关
*/
private Boolean enabled;
/**
* 验证码类型math 数组计算 char 字符
*/
private String type;
public Boolean getEnabled()
{
return enabled;
}
public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
}

31
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/config/properties/IgnoreWhiteProperties.java

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
package com.ecell.internationalize.gateway.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author borui
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.ignore")
public class IgnoreWhiteProperties {
/**
* 放行白名单配置网关不校验此处的白名单
*/
private List<String> whites = new ArrayList<>();
public List<String> getWhites()
{
return whites;
}
public void setWhites(List<String> whites)
{
this.whites = whites;
}
}

109
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/constant/MessagesConstant.java

@ -0,0 +1,109 @@ @@ -0,0 +1,109 @@
package com.ecell.internationalize.gateway.constant;
import com.ecell.internationalize.common.core.utils.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import java.util.List;
/**
* @author borui
*/
public class MessagesConstant {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(MessagesConstant.class);
/**令牌不能为空*/
public static final String MESSAGES_TOKE_EMPTY_EN="Token cannot be empty";
public static final String MESSAGES_TOKE_EMPTY_ZH="令牌不能为空";
/**令牌已过期或验证不正确*/
public static final String MESSAGES_TOKE_EMPTY_OR_ERROR_EN="Token expired or incorrectly verified";
public static final String MESSAGES_TOKE_EMPTY_OR_ERROR_ZH="令牌已过期或验证不正确";
/**登录状态已过期*/
public static final String MESSAGES_LOGIN_STATUS_EXPIRED_EN="Login status has expired";
public static final String MESSAGES_LOGIN_STATUS_EXPIRED_ZH="登录状态已过期";
/**令牌验证失败*/
public static final String MESSAGES_TOKE_VERIFICATION_FAILED_EN="Token verification failed";
public static final String MESSAGES_TOKE_VERIFICATION_FAILED_ZH="令牌验证失败";
/**appId 不能为空*/
public static final String MESSAGES_APPID_ISEMPTY_FAILED_EN="appId cannot be empty";
public static final String MESSAGES_APPID_ISEMPTY_FAILED_ZH="appId 不能为空";
/**appKey 不能为空*/
public static final String MESSAGES_APPkEY_ISEMPTY_FAILED_EN="appKey cannot be empty";
public static final String MESSAGES_APPkEY_ISEMPTY_FAILED_ZH="appKey 不能为空";
/**请求地址不允许访问*/
public static final String MESSAGES_REQUEST_ADDRESS_EN="The requested address does not allow access";
public static final String MESSAGES_REQUEST_ADDRESS_ZH="请求地址不允许访问";
/**服务未找到*/
public static final String MESSAGES_SERVICE_NOT_FOUND_EN="Service not found";
public static final String MESSAGES_SERVICE_NOT_FOUND_ZH="服务未找到";
/**内部服务器错误*/
public static final String MESSAGES_INTERNAL_SERVER_ERROR_EN="Internal server error";
public static final String MESSAGES_INTERNAL_SERVER_ERROR_ZH="内部服务器错误";
/**内部服务器错误*/
public static final String MESSAGES_API_STATE_ERROR_EN="This account has been disabled";
public static final String MESSAGES_API_STATE_ERROR_ZH="该账户已被禁用";
public static final String MESSAGES_API_LIMIT_MAX_ERROR_ZH="当前接口达到最大限流次数";
public static final String MESSAGES_API_LIMIT_MAX_ERROR_EN="The current interface has reached the maximum current limit times";
public static final Integer APP_ID_CODE=406;
public static final Integer APP_KEY_CODE=407;
public static final Integer STATE_CODE=408;
public static final Integer LIMIT_CODE=409;
public static final String STRING_ZERO="0";
public static final String STRING_ONE="1";
/**语言类型 中文*/
public static final String Language_ZH="zh";
/**语言类型 英文*/
public static final String Language_EN="en";
/**语言类型 key*/
public static final String HEADER_KEY="yisailanguage";
/**
* 国际化处理
* @param exchange
* @return
*/
public static String getMessages(ServerWebExchange exchange, String zh_msg, String en_msg) {
//给一个默认值
String msg = en_msg;
ServerHttpRequest request = exchange.getRequest();
if (StringUtils.isNotNull(request)) {
if (request.getHeaders().containsKey(MessagesConstant.HEADER_KEY)) {
String zh = exchange.getRequest().getHeaders().getFirst(MessagesConstant.HEADER_KEY);
if (MessagesConstant.Language_ZH.equals(zh)) {
msg = zh_msg;
} else {
msg = en_msg;
}
} else {
List<String> list = request.getHeaders().get("accept-language");
if (StringUtils.isNotEmpty(list) && list.size() > 0) {
String s = list.get(0).split(",")[0].split("-")[0];
log.info("获取头部的accept-language值:", request.getHeaders().get("accept-language"));
log.info("获取头部的语言:{}", s);
if (MessagesConstant.Language_ZH.equals(s)) {
msg = zh_msg;
} else {
msg = en_msg;
}
}
}
} else {
msg = en_msg;
}
return msg;
}
}

99
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/constant/RateLimitInfo.java

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
package com.ecell.internationalize.gateway.constant;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
/**
* @author borui
*/
public class RateLimitInfo implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(example = "APPID")
private Integer appId;
@ApiModelProperty(example = "APPKEY")
private String appKey;
@ApiModelProperty(example = "状态(0:禁用 , 1:启用)")
private String status;
@ApiModelProperty(example = "厂商Id")
private String firmId;
@ApiModelProperty(example = "标识(1:厂商:2:代理商)")
private String firmFlag;
@ApiModelProperty(example = "代理商Id")
private String secondFirmId;
@ApiModelProperty(example = "发起请求秒数(如一分钟多少次,单位为秒)")
private Integer second;
@ApiModelProperty(example = "发起请求次数(如多少分钟100次)")
private Integer frequency;
public Integer getAppId() {
return appId;
}
public void setAppId(Integer appId) {
this.appId = appId;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getFirmId() {
return firmId;
}
public void setFirmId(String firmId) {
this.firmId = firmId;
}
public String getFirmFlag() {
return firmFlag;
}
public void setFirmFlag(String firmFlag) {
this.firmFlag = firmFlag;
}
public String getSecondFirmId() {
return secondFirmId;
}
public void setSecondFirmId(String secondFirmId) {
this.secondFirmId = secondFirmId;
}
public Integer getSecond() {
return second;
}
public void setSecond(Integer second) {
this.second = second;
}
public Integer getFrequency() {
return frequency;
}
public void setFrequency(Integer frequency) {
this.frequency = frequency;
}
}

211
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/AuthFilter.java

@ -0,0 +1,211 @@ @@ -0,0 +1,211 @@
package com.ecell.internationalize.gateway.filter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ecell.internationalize.common.core.constant.CacheConstants;
import com.ecell.internationalize.common.core.constant.HttpStatus;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.constant.TokenConstants;
import com.ecell.internationalize.common.core.utils.JwtUtils;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.redis.service.RedisService;
import com.ecell.internationalize.gateway.config.properties.IgnoreWhiteProperties;
import com.ecell.internationalize.gateway.constant.MessagesConstant;
import com.ecell.internationalize.gateway.constant.RateLimitInfo;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Collections;
/**
* @author borui
*/
@Component
public class AuthFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
private static final String API_URL = "/yisai-system/api/**";
private static final String RATE_LIMIT = "rate_limit:";
private static final String HEADER_APPID = "appid";
private static final String HEADER_APPKEY = "appkey";
// 排除过滤的 uri 地址,nacos自行添加
@Autowired
private IgnoreWhiteProperties ignoreWhite;
@Autowired
private RedisService redisService;
@Autowired
RedisScript<Long> redisScript;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath();
if (StringUtils.isMatch(API_URL, url)) {
return getVoidMono(exchange, chain, request, url);
// return chain.filter(exchange);
}
// 跳过不需要验证的路径
if (StringUtils.matches(url, ignoreWhite.getWhites())) {
return chain.filter(exchange);
}
String token = getToken(request);
if (StringUtils.isEmpty(token)) {
return unauthorizedResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_TOKE_EMPTY_ZH, MessagesConstant.MESSAGES_TOKE_EMPTY_EN));
}
Claims claims = JwtUtils.parseToken(token);
if (claims == null) {
return unauthorizedResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_TOKE_EMPTY_OR_ERROR_ZH, MessagesConstant.MESSAGES_TOKE_EMPTY_OR_ERROR_EN));
}
String userkey = JwtUtils.getUserKey(claims);
boolean islogin = redisService.hasKey(getTokenKey(userkey));
if (!islogin) {
return unauthorizedResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_LOGIN_STATUS_EXPIRED_ZH, MessagesConstant.MESSAGES_LOGIN_STATUS_EXPIRED_EN));
}
String userid = JwtUtils.getUserId(claims);
String username = JwtUtils.getUserName(claims);
if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) {
return unauthorizedResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_TOKE_VERIFICATION_FAILED_ZH, MessagesConstant.MESSAGES_TOKE_VERIFICATION_FAILED_EN));
}
// 设置用户信息到请求
addHeader(mutate, SecurityConstants.USER_KEY, userkey);
addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
// 内部请求来源参数清除
removeHeader(mutate, SecurityConstants.FROM_SOURCE);
return chain.filter(exchange.mutate().request(mutate.build()).build());
}
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
if (value == null) {
return;
}
String valueStr = value.toString();
String valueEncode = ServletUtils.urlEncode(valueStr);
mutate.header(name, valueEncode);
}
private void removeHeader(ServerHttpRequest.Builder mutate, String name) {
mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
}
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
}
private Mono<Void> unauthorizedAPIResponse(ServerWebExchange exchange, String msg, int code) {
log.error("[对外接口鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, code);
}
/**
* 获取缓存key
*/
private String getTokenKey(String token) {
return CacheConstants.LOGIN_TOKEN_KEY + token;
}
/**
* 获取请求token
*/
private String getToken(ServerHttpRequest request) {
String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION);
// 如果前端设置了令牌前缀,则裁剪掉前缀
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) {
token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY);
}
return token;
}
private Mono<Void> getVoidMono(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request, String url) {
Long apiCount;
String appId = request.getHeaders().getFirst(HEADER_APPID);
String appKey = request.getHeaders().getFirst(HEADER_APPKEY);
if (StringUtils.isEmpty(appId)) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_APPID_ISEMPTY_FAILED_ZH, MessagesConstant.MESSAGES_APPID_ISEMPTY_FAILED_EN), MessagesConstant.APP_ID_CODE);
}
if (StringUtils.isEmpty(appId)) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_APPkEY_ISEMPTY_FAILED_ZH, MessagesConstant.MESSAGES_APPkEY_ISEMPTY_FAILED_EN), MessagesConstant.APP_KEY_CODE);
}
String redisKey = appId + "_" + appKey;
if (!redisService.hasKey(redisKey)) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_ZH, MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_EN), 500);
}
try {
Object cacheObject = redisService.getCacheObject(redisKey);
String s = JSON.toJSONString(cacheObject);
RateLimitInfo rateLimitInfo = JSONObject.parseObject(s, RateLimitInfo.class);
if (StringUtils.isNotNull(rateLimitInfo)) {
String status = rateLimitInfo.getStatus();
if (StringUtils.isNotEmpty(status)) {
if (MessagesConstant.STRING_ZERO.equals(status)) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_API_STATE_ERROR_ZH, MessagesConstant.MESSAGES_API_STATE_ERROR_EN), MessagesConstant.STATE_CODE);
}
apiCount = getApiCount(rateLimitInfo, url);
if (apiCount > rateLimitInfo.getFrequency()) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_API_LIMIT_MAX_ERROR_ZH, MessagesConstant.MESSAGES_API_LIMIT_MAX_ERROR_EN), MessagesConstant.LIMIT_CODE);
}
}
}
} catch (Exception e) {
return unauthorizedAPIResponse(exchange, MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_ZH, MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_EN), 500);
}
return chain.filter(exchange);
}
private Long getApiCount(RateLimitInfo info, String url) {
Long current;
int time = 0, count = 0;
String fid;
StringBuffer buffer = new StringBuffer(RATE_LIMIT);
if (MessagesConstant.STRING_ONE.equals(info.getFirmFlag())) {
fid = info.getFirmId();
} else {
fid = info.getSecondFirmId();
}
String rateKey = buffer.append(fid).append(url).toString();
time = info.getSecond();
if (time <= 0) {
time = 60;
}
count = info.getFrequency();
if (count <= 0) {
count = 10;
}
current = (Long) redisService.redisTemplate.execute(redisScript, Collections.singletonList(rateKey), time, count);
return current;
}
@Override
public int getOrder() {
return -200;
}
}

57
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/BlackListUrlFilter.java

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
package com.ecell.internationalize.gateway.filter;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.gateway.constant.MessagesConstant;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* @author borui
*/
@Component
public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> {
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String url = exchange.getRequest().getURI().getPath();
if (config.matchBlacklist(url)) {
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), MessagesConstant.getMessages(exchange, MessagesConstant.MESSAGES_REQUEST_ADDRESS_ZH, MessagesConstant.MESSAGES_REQUEST_ADDRESS_EN));
}
return chain.filter(exchange);
};
}
public BlackListUrlFilter() {
super(Config.class);
}
public static class Config {
private List<String> blacklistUrl;
private List<Pattern> blacklistUrlPattern = new ArrayList<>();
public boolean matchBlacklist(String url) {
return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find());
}
public List<String> getBlacklistUrl() {
return blacklistUrl;
}
public void setBlacklistUrl(List<String> blacklistUrl) {
this.blacklistUrl = blacklistUrl;
this.blacklistUrlPattern.clear();
this.blacklistUrl.forEach(url -> {
this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE));
});
}
}
}

86
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/filter/CacheRequestFilter.java

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
package com.ecell.internationalize.gateway.filter;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.List;
/**
* @author borui
*/
@Component
public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config> {
public CacheRequestFilter()
{
super(Config.class);
}
@Override
public String name()
{
return "CacheRequestFilter";
}
@Override
public GatewayFilter apply(Config config)
{
CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter();
Integer order = config.getOrder();
if (order == null)
{
return cacheRequestGatewayFilter;
}
return new OrderedGatewayFilter(cacheRequestGatewayFilter, order);
}
public static class CacheRequestGatewayFilter implements GatewayFilter
{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
// GET DELETE 不过滤
HttpMethod method = exchange.getRequest().getMethod();
if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE)
{
return chain.filter(exchange);
}
return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> {
if (serverHttpRequest == exchange.getRequest())
{
return chain.filter(exchange);
}
return chain.filter(exchange.mutate().request(serverHttpRequest).build());
});
}
}
@Override
public List<String> shortcutFieldOrder()
{
return Collections.singletonList("order");
}
static class Config
{
private Integer order;
public Integer getOrder()
{
return order;
}
public void setOrder(Integer order)
{
this.order = order;
}
}
}

58
ecell-internationalize/ecell-internationalize-gateway/src/main/java/com/ecell/internationalize/gateway/handler/GatewayExceptionHandler.java

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
package com.ecell.internationalize.gateway.handler;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.gateway.constant.MessagesConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author borui
*/
@Order(-1)
@Configuration
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class);
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
ServerHttpResponse response = exchange.getResponse();
if (exchange.getResponse().isCommitted())
{
return Mono.error(ex);
}
String msg;
if (ex instanceof NotFoundException)
{
/**服务未找到*/
msg = MessagesConstant.getMessages(exchange,MessagesConstant.MESSAGES_SERVICE_NOT_FOUND_ZH,MessagesConstant.MESSAGES_SERVICE_NOT_FOUND_EN);
}
else if (ex instanceof ResponseStatusException)
{
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
msg = responseStatusException.getMessage();
}
else
{
/**内部服务器错误*/
//msg="内部服务器错误";
msg =MessagesConstant.getMessages(exchange,MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_ZH,MessagesConstant.MESSAGES_INTERNAL_SERVER_ERROR_EN);
}
log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage());
return ServletUtils.webFluxResponseWriter(response, msg);
}
}

74
ecell-internationalize/ecell-internationalize-gateway/src/main/resources/application-dev.yml

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
spring:
redis:
host: 120.77.209.176
port: 6379
database: 0
password: Ecell...20201001
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
routes:
# 认证中心
- id: ecell-internationalize-auth
uri: lb://ecell-internationalize-auth
predicates:
- Path=/auth/**
filters:
# 验证码处理
- CacheRequestFilter
- ValidateCodeFilter
- StripPrefix=1
#易赛系统服务
- id: yisai-system
uri: lb://yisai-system
predicates:
- Path=/yisai_system/**
filters:
- StripPrefix=1
#易赛授权服务
- id: yisai-system-security
uri: lb://yisai-system-security
predicates:
- Path=/yisai_security/**
filters:
- StripPrefix=1
#易赛APP服务
- id: yisai-app
uri: lb://yisai-app
predicates:
- Path=/yisai_app/**
filters:
- StripPrefix=1
# 安全配置
security:
# 验证码
captcha:
enabled: true
type: math
# 防止XSS攻击
xss:
enabled: true
excludeUrls:
- /system/notice
# 不校验白名单
ignore:
whites:
- /auth/logout
- /auth/login
- /auth/register
- /*/v2/api-docs
- /csrf
- /yisai_auth/*/login
- /yisai_auth/*/logout
- /yisai_api/api/**
- /yisai_system/api/**
cors:
enabled: true

40
ecell-internationalize/ecell-internationalize-gateway/src/main/resources/bootstrap.yml

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
# Tomcat
server:
port: 9997
# Spring
spring:
application:
# 应用名称
name: ecell-internationalize-gateway
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# sentinel:
# # 取消控制台懒加载
# eager: true
# transport:
# # 控制台地址
# dashboard: 127.0.0.1:8718
# # nacos配置持久化
# datasource:
# ds1:
# nacos:
# server-addr: 127.0.0.1:8848
# dataId: sentinel-ruoyi-gateway
# groupId: DEFAULT_GROUP
# data-type: json
# rule-type: flow

15
ecell-internationalize/ecell-internationalize-gateway/src/main/resources/lua/rateLimit.lua

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
local key = KEYS[1]
local time = tonumber(ARGV[1])
local count = tonumber(ARGV[2])
local current = redis.call('get',key)
if current and tonumber(current) > count then
return tonumber(current)
end
current = redis.call('incr',key)
if tonumber(current)==1 then
redis.call('expire',key,time)
end
return tonumber(current)
Loading…
Cancel
Save