Commit 926c75d29a6e956c12e5e6616349f9f35692fdc0
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
yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService
yudao-framework/yudao-spring-boot-starter-captcha/src/main/resources/META-INF/spring.factories
0 → 100644
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
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 |