Commit 926c75d29a6e956c12e5e6616349f9f35692fdc0

Authored by YunaiV
1 parent 020535ab

优化图片验证码的后端实现

Showing 13 changed files with 117 additions and 121 deletions
yudao-framework/yudao-spring-boot-starter-captcha/pom.xml
@@ -12,8 +12,8 @@ @@ -12,8 +12,8 @@
12 <packaging>jar</packaging> 12 <packaging>jar</packaging>
13 13
14 <name>${project.artifactId}</name> 14 <name>${project.artifactId}</name>
15 - <description>  
16 - 验证码 15 + <description>验证码拓展
  16 + 1. 基于 aj-captcha 实现图形验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
17 </description> 17 </description>
18 18
19 <dependencies> 19 <dependencies>
@@ -23,9 +23,10 @@ @@ -23,9 +23,10 @@
23 <artifactId>spring-boot-starter</artifactId> 23 <artifactId>spring-boot-starter</artifactId>
24 </dependency> 24 </dependency>
25 25
  26 + <!-- DB 相关 -->
26 <dependency> 27 <dependency>
27 - <groupId>cn.iocoder.boot</groupId>  
28 - <artifactId>yudao-spring-boot-starter-redis</artifactId> 28 + <groupId>org.springframework.boot</groupId>
  29 + <artifactId>spring-boot-starter-data-redis</artifactId>
29 </dependency> 30 </dependency>
30 31
31 <!-- 验证码相关 --> 32 <!-- 验证码相关 -->
@@ -33,7 +34,6 @@ @@ -33,7 +34,6 @@
33 <groupId>com.anji-plus</groupId> 34 <groupId>com.anji-plus</groupId>
34 <artifactId>spring-boot-starter-captcha</artifactId> 35 <artifactId>spring-boot-starter-captcha</artifactId>
35 </dependency> 36 </dependency>
36 -  
37 </dependencies> 37 </dependencies>
38 38
39 </project> 39 </project>
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.captcha.config;
  2 +
  3 +import cn.hutool.core.util.ClassUtil;
  4 +import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
  5 +import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
  6 +import com.anji.captcha.service.CaptchaCacheService;
  7 +import org.springframework.context.annotation.Bean;
  8 +import org.springframework.context.annotation.Configuration;
  9 +import org.springframework.data.redis.core.StringRedisTemplate;
  10 +
  11 +@Configuration
  12 +public class YudaoCaptchaConfiguration {
  13 +
  14 + static {
  15 + // 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
  16 + // 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
  17 + ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName());
  18 + }
  19 +
  20 + @Bean
  21 + public CaptchaCacheService captchaCacheService(StringRedisTemplate stringRedisTemplate) {
  22 + return new RedisCaptchaServiceImpl(stringRedisTemplate);
  23 + }
  24 +
  25 +}
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/captcha/core/service/CaptchaServiceImpl.java renamed to yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/service/RedisCaptchaServiceImpl.java
1 -package cn.iocoder.yudao.captcha.core.service; 1 +package cn.iocoder.yudao.framework.captcha.core.service;
2 2
3 import com.anji.captcha.service.CaptchaCacheService; 3 import com.anji.captcha.service.CaptchaCacheService;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.RequiredArgsConstructor;
4 import org.springframework.data.redis.core.StringRedisTemplate; 7 import org.springframework.data.redis.core.StringRedisTemplate;
5 -import org.springframework.stereotype.Service;  
6 8
7 import javax.annotation.Resource; 9 import javax.annotation.Resource;
8 import java.util.concurrent.TimeUnit; 10 import java.util.concurrent.TimeUnit;
9 11
10 -@Service  
11 -public class CaptchaServiceImpl implements CaptchaCacheService { 12 +/**
  13 + * 基于 Redis 实现验证码的存储
  14 + *
  15 + * @author 星语
  16 + */
  17 +@NoArgsConstructor // 保证 aj-captcha 的 SPI 创建
  18 +@AllArgsConstructor
  19 +public class RedisCaptchaServiceImpl implements CaptchaCacheService {
  20 +
  21 + @Resource // 保证 aj-captcha 的 SPI 创建时的注入
  22 + private StringRedisTemplate stringRedisTemplate;
12 23
13 @Override 24 @Override
14 public String type() { 25 public String type() {
15 return "redis"; 26 return "redis";
16 } 27 }
17 28
18 - @Resource  
19 - private StringRedisTemplate stringRedisTemplate;  
20 -  
21 @Override 29 @Override
22 public void set(String key, String value, long expiresInSeconds) { 30 public void set(String key, String value, long expiresInSeconds) {
23 stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS); 31 stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
@@ -42,4 +50,5 @@ public class CaptchaServiceImpl implements CaptchaCacheService { @@ -42,4 +50,5 @@ public class CaptchaServiceImpl implements CaptchaCacheService {
42 public Long increment(String key, long val) { 50 public Long increment(String key, long val) {
43 return stringRedisTemplate.opsForValue().increment(key,val); 51 return stringRedisTemplate.opsForValue().increment(key,val);
44 } 52 }
  53 +
45 } 54 }
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/package-info.java 0 → 100644
  1 +/**
  2 + * 验证码拓展
  3 + * 1. 基于 aj-captcha 实现图形验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
  4 + *
  5 + * @author 星语
  6 + */
  7 +package cn.iocoder.yudao.framework.captcha;
yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService
1 -cn.iocoder.yudao.captcha.core.service.CaptchaServiceImpl  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl
yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/spring.factories 0 → 100644
  1 +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2 + cn.iocoder.yudao.framework.captcha.config.YudaoCaptchaConfiguration
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
@@ -12,8 +12,7 @@ public interface ErrorCodeConstants { @@ -12,8 +12,7 @@ public interface ErrorCodeConstants {
12 // ========== AUTH 模块 1002000000 ========== 12 // ========== AUTH 模块 1002000000 ==========
13 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1002000000, "登录失败,账号密码不正确"); 13 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1002000000, "登录失败,账号密码不正确");
14 ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1002000001, "登录失败,账号被禁用"); 14 ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1002000001, "登录失败,账号被禁用");
15 - ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在");  
16 - ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); 15 + ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确,原因:{}");
17 ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); 16 ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定");
18 ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1002000006, "Token 已经过期"); 17 ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1002000006, "Token 已经过期");
19 ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1002000007, "手机号不存在"); 18 ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1002000007, "手机号不存在");
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java
@@ -33,8 +33,10 @@ public class AuthLoginReqVO { @@ -33,8 +33,10 @@ public class AuthLoginReqVO {
33 @Length(min = 4, max = 16, message = "密码长度为 4-16 位") 33 @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
34 private String password; 34 private String password;
35 35
36 - @ApiModelProperty(value = "验证码", required = true, example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==")  
37 - @NotEmpty(message = "验证码不能为空") 36 + @ApiModelProperty(value = "验证码", required = true,
  37 + example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==",
  38 + notes = "验证码开启时,需要传递")
  39 + @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class)
38 private String captchaVerification; 40 private String captchaVerification;
39 41
40 // ========== 绑定社交登录时,需要传递如下参数 ========== 42 // ========== 绑定社交登录时,需要传递如下参数 ==========
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/captcha/config/CaptchaConfig.java deleted
1 -package cn.iocoder.yudao.module.system.framework.captcha.config;  
2 -  
3 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
4 -import org.springframework.context.annotation.Configuration;  
5 -  
6 -@Configuration  
7 -@EnableConfigurationProperties(CaptchaProperties.class)  
8 -public class CaptchaConfig {  
9 -}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/captcha/config/CaptchaProperties.java deleted
1 -package cn.iocoder.yudao.module.system.framework.captcha.config;  
2 -  
3 -import lombok.Data;  
4 -import org.springframework.boot.context.properties.ConfigurationProperties;  
5 -import org.springframework.validation.annotation.Validated;  
6 -  
7 -import javax.validation.constraints.NotNull;  
8 -import java.time.Duration;  
9 -  
10 -@ConfigurationProperties(prefix = "yudao.captcha")  
11 -@Validated  
12 -@Data  
13 -public class CaptchaProperties {  
14 -  
15 - private static final Boolean ENABLE_DEFAULT = true;  
16 -  
17 - /**  
18 - * 是否开启  
19 - * 注意,这里仅仅是后端 Server 是否校验,暂时不控制前端的逻辑  
20 - */  
21 - private Boolean enable = ENABLE_DEFAULT;  
22 - /**  
23 - * 验证码的过期时间  
24 - */  
25 - @NotNull(message = "验证码的过期时间不为空")  
26 - private Duration timeout;  
27 - /**  
28 - * 验证码的高度  
29 - */  
30 - @NotNull(message = "验证码的高度不能为空")  
31 - private Integer height;  
32 - /**  
33 - * 验证码的宽度  
34 - */  
35 - @NotNull(message = "验证码的宽度不能为空")  
36 - private Integer width;  
37 -  
38 -}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/captcha/package-info.java deleted
1 -/**  
2 - * 基于 Hutool captcha 库,实现验证码功能  
3 - */  
4 -package cn.iocoder.yudao.module.system.framework.captcha;  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; 6 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
7 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; 7 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
  8 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
8 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; 9 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
9 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 10 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
10 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 11 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
@@ -24,7 +25,9 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; @@ -24,7 +25,9 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService;
24 import com.anji.captcha.model.common.ResponseModel; 25 import com.anji.captcha.model.common.ResponseModel;
25 import com.anji.captcha.model.vo.CaptchaVO; 26 import com.anji.captcha.model.vo.CaptchaVO;
26 import com.anji.captcha.service.CaptchaService; 27 import com.anji.captcha.service.CaptchaService;
  28 +import com.google.common.annotations.VisibleForTesting;
27 import lombok.extern.slf4j.Slf4j; 29 import lombok.extern.slf4j.Slf4j;
  30 +import org.springframework.beans.factory.annotation.Value;
28 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
29 32
30 import javax.annotation.Resource; 33 import javax.annotation.Resource;
@@ -61,6 +64,12 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -61,6 +64,12 @@ public class AdminAuthServiceImpl implements AdminAuthService {
61 @Resource 64 @Resource
62 private SmsCodeApi smsCodeApi; 65 private SmsCodeApi smsCodeApi;
63 66
  67 + /**
  68 + * 验证码的开关,默认为 true
  69 + */
  70 + @Value("${yudao.captcha.enable:true}")
  71 + private Boolean captchaEnable;
  72 +
64 @Override 73 @Override
65 public AdminUserDO authenticate(String username, String password) { 74 public AdminUserDO authenticate(String username, String password) {
66 final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME; 75 final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
@@ -84,23 +93,19 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -84,23 +93,19 @@ public class AdminAuthServiceImpl implements AdminAuthService {
84 93
85 @Override 94 @Override
86 public AuthLoginRespVO login(AuthLoginReqVO reqVO) { 95 public AuthLoginRespVO login(AuthLoginReqVO reqVO) {
87 - CaptchaVO captchaVO = new CaptchaVO();  
88 - captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification());  
89 - ResponseModel response = captchaService.verification(captchaVO);  
90 - if(response.isSuccess()){  
91 - // 使用账号密码,进行登录  
92 - AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());  
93 -  
94 - // 如果 socialType 非空,说明需要绑定社交用户  
95 - if (reqVO.getSocialType() != null) {  
96 - socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),  
97 - reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));  
98 - }  
99 - // 创建 Token 令牌,记录登录日志  
100 - return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);  
101 - }else{  
102 - throw exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR); 96 + // 校验验证码
  97 + verifyCaptcha(reqVO);
  98 +
  99 + // 使用账号密码,进行登录
  100 + AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword());
  101 +
  102 + // 如果 socialType 非空,说明需要绑定社交用户
  103 + if (reqVO.getSocialType() != null) {
  104 + socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
  105 + reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));
103 } 106 }
  107 + // 创建 Token 令牌,记录登录日志
  108 + return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
104 } 109 }
105 110
106 @Override 111 @Override
@@ -172,6 +177,25 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -172,6 +177,25 @@ public class AdminAuthServiceImpl implements AdminAuthService {
172 return AuthConvert.INSTANCE.convert(accessTokenDO); 177 return AuthConvert.INSTANCE.convert(accessTokenDO);
173 } 178 }
174 179
  180 + @VisibleForTesting
  181 + void verifyCaptcha(AuthLoginReqVO reqVO) {
  182 + // 如果验证码关闭,则不进行校验
  183 + if (!captchaEnable) {
  184 + return;
  185 + }
  186 + // 校验验证码
  187 + ValidationUtils.validate(validator, reqVO, AuthLoginReqVO.CodeEnableGroup.class);
  188 + CaptchaVO captchaVO = new CaptchaVO();
  189 + captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification());
  190 + ResponseModel response = captchaService.verification(captchaVO);
  191 + // 验证不通过
  192 + if (!response.isSuccess()) {
  193 + // 创建登录失败日志(验证码不正确)
  194 + createLoginLog(null, reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.CAPTCHA_CODE_ERROR);
  195 + throw exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR, response.getRepMsg());
  196 + }
  197 + }
  198 +
175 private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) { 199 private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
176 // 插入登陆日志 200 // 插入登陆日志
177 createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS); 201 createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
yudao-server/src/main/resources/application.yaml
@@ -61,38 +61,20 @@ mybatis-plus: @@ -61,38 +61,20 @@ mybatis-plus:
61 61
62 aj: 62 aj:
63 captcha: 63 captcha:
64 - # 滑动验证,底图路径,不配置将使用默认图片  
65 - # 支持全路径  
66 - # 支持项目路径,以classpath:开头,取resource目录下路径,例:classpath:images/jigsaw  
67 - jigsaw: classpath:images/jigsaw  
68 - #滑动验证,底图路径,不配置将使用默认图片  
69 - ##支持全路径  
70 - # 支持项目路径,以classpath:开头,取resource目录下路径,例:classpath:images/pic-click  
71 - pic-click: classpath:images/pic-click  
72 - # 缓存local/redis...  
73 - cache-type: redis  
74 - # local缓存的阈值,达到这个值,清除缓存  
75 - cache-number: 1000  
76 - # local定时清除过期缓存(单位秒),设置为0代表不执行  
77 - timing-clear: 180  
78 - # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选  
79 - type: blockPuzzle  
80 - # 右下角水印文字(我的水印)https://tool.chinaz.com/tools/unicode.aspx 中文转Unicode Linux可能需要转unicode  
81 - water-mark: 芋道源码  
82 - # 滑动干扰项(0/1/2)  
83 - interference-options: 2  
84 - # 接口请求次数一分钟限制是否开启 true|false  
85 - req-frequency-limit-enable: true  
86 - # 验证失败5次,get接口锁定  
87 - req-get-lock-limit: 5  
88 - # 验证失败后,锁定时间间隔,s  
89 - req-get-lock-seconds: 10  
90 - # get接口一分钟内请求数限制  
91 - req-get-minute-limit: 30  
92 - # check接口一分钟内请求数限制  
93 - req-check-minute-limit: 60  
94 - # verify接口一分钟内请求数限制  
95 - req-verify-minute-limit: 60 64 + jigsaw: classpath:images/jigsaw # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
  65 + pic-click: classpath:images/pic-click # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
  66 + cache-type: redis # 缓存 local/redis...
  67 + cache-number: 1000 # local 缓存的阈值,达到这个值,清除缓存
  68 + timing-clear: 180 # local定时清除过期缓存(单位秒),设置为0代表不执行
  69 + type: blockPuzzle # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选
  70 + water-mark: 芋道源码 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 Unicode,Linux 可能需要转 unicode
  71 + interference-options: 2 # 滑动干扰项(0/1/2)
  72 + req-frequency-limit-enable: false # 接口请求次数一分钟限制是否开启 true|false
  73 + req-get-lock-limit: 5 # 验证失败5次,get接口锁定
  74 + req-get-lock-seconds: 10 # 验证失败后,锁定时间间隔
  75 + req-get-minute-limit: 30 # get 接口一分钟内请求数限制
  76 + req-check-minute-limit: 60 # check 接口一分钟内请求数限制
  77 + req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制
96 78
97 --- #################### 芋道相关配置 #################### 79 --- #################### 芋道相关配置 ####################
98 80
@@ -112,9 +94,7 @@ yudao: @@ -112,9 +94,7 @@ yudao:
112 version: ${yudao.info.version} 94 version: ${yudao.info.version}
113 base-package: ${yudao.info.base-package} 95 base-package: ${yudao.info.base-package}
114 captcha: 96 captcha:
115 - timeout: 5m  
116 - width: 160  
117 - height: 60 97 + enable: true # 验证码的开关,默认为 true;注意,优先读取数据库 infra_config 的 yudao.captcha.enable,所以请从数据库修改,可能需要重启项目
118 codegen: 98 codegen:
119 base-package: ${yudao.info.base-package} 99 base-package: ${yudao.info.base-package}
120 db-schemas: ${spring.datasource.dynamic.datasource.master.name} 100 db-schemas: ${spring.datasource.dynamic.datasource.master.name}
@@ -134,8 +114,7 @@ yudao: @@ -134,8 +114,7 @@ yudao:
134 - /admin-api/infra/file/*/get/** # 获取图片,和租户无关 114 - /admin-api/infra/file/*/get/** # 获取图片,和租户无关
135 - /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号 115 - /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
136 - /app-api/pay/order/notify/* # 支付回调通知,不携带租户编号 116 - /app-api/pay/order/notify/* # 支付回调通知,不携带租户编号
137 -# - /jmreport/list  
138 - - /jmreport/* 117 + - /jmreport/* # 积木报表,无法携带租户编号
139 ignore-tables: 118 ignore-tables:
140 - system_tenant 119 - system_tenant
141 - system_tenant_package 120 - system_tenant_package