Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/captcha/core/RedisCaptchaServiceImpl.java
|
@ -131,16 +131,6 @@
|
||||||
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-captcha</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-desensitize</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Spring 核心 -->
|
<!-- Spring 核心 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
<module>yudao-spring-boot-starter-biz-ip</module>
|
<module>yudao-spring-boot-starter-biz-ip</module>
|
||||||
|
|
||||||
<module>yudao-spring-boot-starter-flowable</module>
|
<module>yudao-spring-boot-starter-flowable</module>
|
||||||
<module>yudao-spring-boot-starter-captcha</module>
|
|
||||||
<module>yudao-spring-boot-starter-websocket</module>
|
<module>yudao-spring-boot-starter-websocket</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-framework</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>yudao-spring-boot-starter-captcha</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>${project.artifactId}</name>
|
|
||||||
<description>验证码拓展
|
|
||||||
1. 基于 aj-captcha 实现滑块验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.xingyuv</groupId>
|
|
||||||
<artifactId>spring-boot-starter-captcha-plus</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- Spring 核心 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DB 相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,29 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.captcha.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
|
|
||||||
import com.xingyuv.captcha.properties.AjCaptchaProperties;
|
|
||||||
import com.xingyuv.captcha.service.CaptchaCacheService;
|
|
||||||
import com.xingyuv.captcha.service.impl.CaptchaServiceFactory;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
@AutoConfiguration
|
|
||||||
public class YudaoCaptchaConfiguration {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CaptchaCacheService captchaCacheService(AjCaptchaProperties config) {
|
|
||||||
// 缓存类型 redis/local/....
|
|
||||||
CaptchaCacheService ret = CaptchaServiceFactory.getCache(config.getCacheType().name());
|
|
||||||
if (ret instanceof RedisCaptchaServiceImpl) {
|
|
||||||
((RedisCaptchaServiceImpl) ret).setStringRedisTemplate(stringRedisTemplate);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.captcha.core.enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码 Redis Key 枚举类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public interface CaptchaRedisKeyConstants {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码的请求限流
|
|
||||||
*
|
|
||||||
* KEY 格式:AJ.CAPTCHA.REQ.LIMIT-%s-%s
|
|
||||||
* VALUE 数据类型:String // 例如说:验证失败 5 次,get 接口锁定
|
|
||||||
* 过期时间:60 秒
|
|
||||||
*/
|
|
||||||
String AJ_CAPTCHA_REQ_LIMIT = "AJ.CAPTCHA.REQ.LIMIT-%s-%s";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码的坐标
|
|
||||||
*
|
|
||||||
* KEY 格式:RUNNING:CAPTCHA:%s // AbstractCaptchaService.REDIS_CAPTCHA_KEY
|
|
||||||
* VALUE 数据类型:String // PointVO.class {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
|
|
||||||
* 过期时间:120 秒
|
|
||||||
*/
|
|
||||||
String AJ_CAPTCHA_RUNNING = "RUNNING:CAPTCHA:%s";
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
/**
|
|
||||||
* 验证码拓展
|
|
||||||
* 1. 基于 aj-captcha 实现滑块验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
|
|
||||||
*
|
|
||||||
* @author 星语
|
|
||||||
*/
|
|
||||||
package cn.iocoder.yudao.framework.captcha;
|
|
|
@ -1 +0,0 @@
|
||||||
cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl
|
|
|
@ -1 +0,0 @@
|
||||||
cn.iocoder.yudao.framework.captcha.config.YudaoCaptchaConfiguration
|
|
|
@ -98,11 +98,6 @@
|
||||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-captcha</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-mail</artifactId>
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
@ -135,6 +130,11 @@
|
||||||
<groupId>com.tencentcloudapi</groupId>
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
<artifactId>tencentcloud-sdk-java-sms</artifactId> <!-- 短信(腾讯云) -->
|
<artifactId>tencentcloud-sdk-java-sms</artifactId> <!-- 短信(腾讯云) -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xingyuv</groupId>
|
||||||
|
<artifactId>spring-boot-starter-captcha-plus</artifactId> <!-- 验证码,一般用于登录使用 -->
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package cn.iocoder.yudao.module.system.framework.captcha.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.system.framework.captcha.core.RedisCaptchaServiceImpl;
|
||||||
|
import com.xingyuv.captcha.properties.AjCaptchaProperties;
|
||||||
|
import com.xingyuv.captcha.service.CaptchaCacheService;
|
||||||
|
import com.xingyuv.captcha.service.impl.CaptchaServiceFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
public class YudaoCaptchaConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CaptchaCacheService captchaCacheService(AjCaptchaProperties config,
|
||||||
|
StringRedisTemplate stringRedisTemplate) {
|
||||||
|
CaptchaCacheService captchaCacheService = CaptchaServiceFactory.getCache(config.getCacheType().name());
|
||||||
|
if (captchaCacheService instanceof RedisCaptchaServiceImpl) {
|
||||||
|
((RedisCaptchaServiceImpl) captchaCacheService).setStringRedisTemplate(stringRedisTemplate);
|
||||||
|
}
|
||||||
|
return captchaCacheService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
package cn.iocoder.yudao.framework.captcha.core.service;
|
package cn.iocoder.yudao.module.system.framework.captcha.core;
|
||||||
|
|
||||||
import com.xingyuv.captcha.service.CaptchaCacheService;
|
import com.xingyuv.captcha.service.CaptchaCacheService;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.Setter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,11 +11,9 @@ import java.util.concurrent.TimeUnit;
|
||||||
*
|
*
|
||||||
* @author 星语
|
* @author 星语
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor // 保证 aj-captcha 的 SPI 创建
|
@Setter
|
||||||
@AllArgsConstructor
|
|
||||||
public class RedisCaptchaServiceImpl implements CaptchaCacheService {
|
public class RedisCaptchaServiceImpl implements CaptchaCacheService {
|
||||||
|
|
||||||
@Resource // 保证 aj-captcha 的 SPI 创建时的注入
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,10 +21,6 @@ public class RedisCaptchaServiceImpl implements CaptchaCacheService {
|
||||||
return "redis";
|
return "redis";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
|
|
||||||
this.stringRedisTemplate = stringRedisTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(String key, String value, long expiresInSeconds) {
|
public void set(String key, String value, long expiresInSeconds) {
|
||||||
stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
|
stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* 验证码拓展
|
||||||
|
*
|
||||||
|
* 基于 aj-captcha 实现滑块验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
|
||||||
|
*
|
||||||
|
* @author 星语
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.system.framework.captcha;
|
|
@ -0,0 +1 @@
|
||||||
|
cn.iocoder.yudao.module.system.framework.captcha.core.RedisCaptchaServiceImpl
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
@ -208,8 +208,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
|
||||||
public void testSmsLogin_success() {
|
public void testSmsLogin_success() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String mobile = randomString();
|
String mobile = randomString();
|
||||||
String scene = randomString();
|
String code = randomString();
|
||||||
AuthSmsLoginReqVO reqVO = new AuthSmsLoginReqVO(mobile, scene);
|
AuthSmsLoginReqVO reqVO = new AuthSmsLoginReqVO(mobile, code);
|
||||||
// mock 方法(用户信息)
|
// mock 方法(用户信息)
|
||||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L));
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L));
|
||||||
when(userService.getUserByMobile(eq(mobile))).thenReturn(user);
|
when(userService.getUserByMobile(eq(mobile))).thenReturn(user);
|
||||||
|
|