diff --git a/README.md b/README.md index 003a39045..f31c02b89 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,7 @@ > 系统演示: [传送门](https://plus-doc.dromara.org/#/common/demo_system) -> 官方前端项目地址: 基于 Vue + ElementPlus 版本前端项目 [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/CrazyLionCat/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)
-> 官方前端项目地址: 基于 React + Ant Design 版本前端项目 [plus-ui-react](https://gitee.com/JavaLionLi/plus-ui/tree/6.X-React/) +> 官方前端项目地址: [gitee](https://gitee.com/JavaLionLi/plus-ui) - [github](https://github.com/CrazyLionCat/plus-ui) - [gitcode](https://gitcode.com/dromara/plus-ui)
> 成员前端项目地址: 基于vben5 [ruoyi-plus-vben5](https://github.com/imdap/ruoyi-plus-vben5)
> 成员前端项目地址: 基于soybean [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean)
> 成员项目地址: 删除多租户与工作流 [RuoYi-Vue-Plus-Single](https://gitee.com/ColorDreams/RuoYi-Vue-Plus-Single)
diff --git a/pom.xml b/pom.xml index 8494ba12b..5fbc914e9 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,8 @@ 1.3.0 + + 1.5.5 3.3.7 @@ -408,6 +410,13 @@ ${ip2region.version} + + + cloud.tianai.captcha + tianai-captcha-springboot-starter + ${tianai-captcha.version} + + org.dromara diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 8f2d51cdf..5489be138 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -117,6 +117,12 @@ test + + + org.dromara + ruoyi-common-captcha + + diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java index e5037f5e8..00537563f 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java @@ -16,7 +16,7 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.log.event.LoginInfoEvent; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.web.config.properties.CaptchaProperties; +import org.dromara.common.captcha.config.properties.CaptchaProperties; import org.dromara.system.api.model.RegisterBody; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.bo.SysUserBo; diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java index cdb6022c7..bcfaf881c 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java @@ -19,7 +19,7 @@ import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.web.config.properties.CaptchaProperties; +import org.dromara.common.captcha.config.properties.CaptchaProperties; import org.dromara.system.api.model.LoginUser; import org.dromara.system.api.model.PasswordLoginBody; import org.dromara.system.domain.SysUser; diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index ae9b6ff9e..d27d2d3ab 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -155,7 +155,7 @@ spring.data: # 数据库索引 database: 0 # redis 密码必须配置 - password: ruoyi123 + # password: ruoyi123 # 连接超时时间 timeout: 10s # 是否开启ssl diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index ec1e1d1a9..e2242ea78 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -15,7 +15,7 @@ server: # 最大线程数 max: 256 -captcha: +image-captcha: # 是否启用验证码校验 enable: true # 验证码类型 math 数组计算 char 字符验证 @@ -25,6 +25,39 @@ captcha: # 字符验证码长度 charLength: 4 +# 行为验证码配置, 详细请看 cloud.tianai.captcha.autoconfiguration.ImageCaptchaProperties 类 +captcha: + # 如果项目中使用到了redis,滑块验证码会自动把验证码数据存到redis中, 这里配置redis的key的前缀,默认是captcha:slider + prefix: captcha + # 验证码过期时间,默认是2分钟,单位毫秒, 可以根据自身业务进行调整 + expire: + # 默认缓存时间 2分钟 + default: 10000 + # 针对 点选验证码 过期时间设置为 2分钟, 因为点选验证码验证比较慢,把过期时间调整大一些 + WORD_IMAGE_CLICK: 20000 + # 使用加载系统自带的资源, 默认是 false(这里系统的默认资源包含 滑动验证码模板/旋转验证码模板,如果想使用系统的模板,这里设置为true) + init-default-resource: true + # 缓存控制, 默认为false不开启 + local-cache-enabled: false + # 缓存开启后,验证码会提前缓存一些生成好的验证数据, 默认是20 + local-cache-size: 20 + # 缓存开启后,缓存拉取失败后等待时间 默认是 5秒钟 + local-cache-wait-time: 5000 + # 缓存开启后,缓存检查间隔 默认是2秒钟 + local-cache-period: 2000 + # 缓存开启后,忽略的字段,默认是 ""(不忽略任何字段) + local-cache-ignored-cache-fields: "" + # 配置字体包,供文字点选验证码使用,可以配置多个,不配置使用默认的字体 + font-path: + - classpath:font/SimHei.ttf + secondary: + # 二次验证, 默认false 不开启 + enabled: true + # 二次验证过期时间, 默认 2分钟 + expire: 240000 + # 二次验证缓存key前缀,默认是 captcha:secondary + keyPrefix: "captcha:secondary" + # 日志配置 logging: level: diff --git a/ruoyi-admin/src/main/resources/bgimages/48.jpg b/ruoyi-admin/src/main/resources/bgimages/48.jpg new file mode 100644 index 000000000..ae731e4ee Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/48.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/a.jpg b/ruoyi-admin/src/main/resources/bgimages/a.jpg new file mode 100644 index 000000000..cef38ec0d Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/a.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/b.jpg b/ruoyi-admin/src/main/resources/bgimages/b.jpg new file mode 100644 index 000000000..72fdb5639 Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/b.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/c.jpg b/ruoyi-admin/src/main/resources/bgimages/c.jpg new file mode 100644 index 000000000..7c8274f02 Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/c.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/d.jpg b/ruoyi-admin/src/main/resources/bgimages/d.jpg new file mode 100644 index 000000000..6057faa35 Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/d.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/e.jpg b/ruoyi-admin/src/main/resources/bgimages/e.jpg new file mode 100644 index 000000000..b5e22e369 Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/e.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/g.jpg b/ruoyi-admin/src/main/resources/bgimages/g.jpg new file mode 100644 index 000000000..ae707ba1b Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/g.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/h.jpg b/ruoyi-admin/src/main/resources/bgimages/h.jpg new file mode 100644 index 000000000..2326c881f Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/h.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/i.jpg b/ruoyi-admin/src/main/resources/bgimages/i.jpg new file mode 100644 index 000000000..f9714d9c9 Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/i.jpg differ diff --git a/ruoyi-admin/src/main/resources/bgimages/j.jpg b/ruoyi-admin/src/main/resources/bgimages/j.jpg new file mode 100644 index 000000000..8f9056f4b Binary files /dev/null and b/ruoyi-admin/src/main/resources/bgimages/j.jpg differ diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 7db451d40..7e1d4519a 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -18,6 +18,7 @@ ruoyi-common-bom ruoyi-common-social + ruoyi-common-captcha ruoyi-common-core ruoyi-common-doc ruoyi-common-excel diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 8d8b12dca..6cd871878 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -19,6 +19,13 @@ + + + org.dromara + ruoyi-common-captcha + ${revision} + + org.dromara diff --git a/ruoyi-common/ruoyi-common-captcha/pom.xml b/ruoyi-common/ruoyi-common-captcha/pom.xml new file mode 100644 index 000000000..ea2c720ba --- /dev/null +++ b/ruoyi-common/ruoyi-common-captcha/pom.xml @@ -0,0 +1,71 @@ + + + + org.dromara + ruoyi-common + ${revision} + + 4.0.0 + + ruoyi-common-captcha + + + ruoyi-common-code 验证码模块 + + + + + org.springframework.boot + spring-boot-autoconfigure + + + org.projectlombok + lombok + + + cn.hutool + hutool-core + + + org.dromara + ruoyi-common-core + + + org.dromara + ruoyi-common-redis + + + org.dromara + ruoyi-common-web + + + org.dromara + ruoyi-common-mail + + + cloud.tianai.captcha + tianai-captcha-springboot-starter + + + org.dromara.sms4j + sms4j-api + 3.3.5 + compile + + + org.dromara.sms4j + sms4j-core + 3.3.5 + compile + + + javax.annotation + javax.annotation-api + 1.3.2 + compile + + + + diff --git a/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/CaptchaConfig.java new file mode 100644 index 000000000..e3efd3800 --- /dev/null +++ b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/CaptchaConfig.java @@ -0,0 +1,45 @@ +package org.dromara.common.captcha.config; + +import cloud.tianai.captcha.common.constant.CaptchaTypeConstant; +import cloud.tianai.captcha.resource.ResourceStore; +import cloud.tianai.captcha.resource.common.model.dto.Resource; +import cloud.tianai.captcha.resource.impl.LocalMemoryResourceStore; +import org.dromara.common.captcha.config.properties.CaptchaProperties; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 验证码配置 + * + * @author Lion Li + */ +@AutoConfiguration +@EnableConfigurationProperties(CaptchaProperties.class) +@Configuration +public class CaptchaConfig { + + + @Bean + public ResourceStore resourceStore() { + // 使用简单的本地内存存储器,实际项目中可以使用数据库等存储 + LocalMemoryResourceStore resourceStore = new LocalMemoryResourceStore(); + + // 2. 添加自定义背景图片 + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/a.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/b.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/c.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/d.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/e.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/g.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/h.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/i.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/j.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/48.jpg", "default")); + resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/48.jpg", "default")); +// resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/c.jpg", "default")); + + return resourceStore; + } +} diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/properties/CaptchaProperties.java similarity index 82% rename from ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java rename to ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/properties/CaptchaProperties.java index 17f165549..0a86e4d26 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java +++ b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/config/properties/CaptchaProperties.java @@ -1,4 +1,4 @@ -package org.dromara.common.web.config.properties; +package org.dromara.common.captcha.config.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -9,7 +9,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * @author Lion Li */ @Data -@ConfigurationProperties(prefix = "captcha") +@ConfigurationProperties(prefix = "image-captcha") public class CaptchaProperties { /** diff --git a/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/utils/CaptchaUtils.java b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/utils/CaptchaUtils.java new file mode 100644 index 000000000..50f3052c4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-captcha/src/main/java/org/dromara/common/captcha/utils/CaptchaUtils.java @@ -0,0 +1,258 @@ +package org.dromara.common.captcha.utils; + +import cloud.tianai.captcha.application.ImageCaptchaApplication; +import cloud.tianai.captcha.application.vo.ImageCaptchaVO; +import cloud.tianai.captcha.common.constant.CaptchaTypeConstant; +import cloud.tianai.captcha.common.response.ApiResponse; +import cloud.tianai.captcha.generator.common.model.dto.GenerateParam; +import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack; +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.captcha.generator.MathGenerator; +import cn.hutool.captcha.generator.RandomGenerator; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.captcha.config.properties.CaptchaProperties; +import org.dromara.common.core.constant.Constants; +import org.dromara.common.core.constant.GlobalConstants; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.regex.RegexValidator; +import org.dromara.common.mail.core.MailBuilder; +import org.dromara.common.redis.annotation.RateLimiter; +import org.dromara.common.redis.enums.LimitType; +import org.dromara.common.redis.utils.RedisUtils; +import org.dromara.common.web.core.WaveAndCircleCaptcha; +import org.dromara.sms4j.api.SmsBlend; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.core.factory.SmsFactory; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.stereotype.Component; + +import java.awt.*; +import java.time.Duration; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 验证码工具类 + * 支持:图形验证码、手机短信验证码、邮箱验证码、行为验证码 + * 规范:一次下发生成验证码、二次校验验证码;内置通用随机码生成、图片生成基础能力 + * + * @author xiaozhi + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class CaptchaUtils { + + private final CaptchaProperties captchaProperties; + private final ImageCaptchaApplication imageCaptchaApplication; + + /** + * SpEL解析器,单例复用,避免频繁创建 + */ + private final ExpressionParser expressionParser = new SpelExpressionParser(); + + + // ====================== 【图形验证码】 ====================== + + /** + * 图片验证码响应对象。 + * + * @param captchaEnabled 是否启用验证码 + * @param uuid 验证码标识 + * @param img Base64 图片数据 + */ + public record CaptchaVo(Boolean captchaEnabled, String uuid, String img) { + } + + /** + * 生成图形验证码 + * 限流:同一IP 60秒最多10次请求 + * + * @return CaptchaVo + */ + @RateLimiter(time = 60, count = 10, limitType = LimitType.IP) + public CaptchaVo generateImageCaptcha() { + boolean captchaEnabled = captchaProperties.getEnable(); + if (!captchaEnabled) { + return new CaptchaVo(false, null, null); + } + // 保存验证码信息 + String uuid = IdUtil.simpleUUID(); + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid; + String captchaType = captchaProperties.getType(); + + CodeGenerator codeGenerator; + if ("math".equals(captchaType)) { + codeGenerator = new MathGenerator(captchaProperties.getNumberLength(), false); + } else { + codeGenerator = new RandomGenerator(captchaProperties.getCharLength()); + } + + WaveAndCircleCaptcha captcha = new WaveAndCircleCaptcha(160, 60); + // captcha.setBackground(Color.WHITE); // 不设置就是透明底 + captcha.setFont(new Font("Arial", Font.BOLD, 45)); + captcha.setGenerator(codeGenerator); + captcha.createCode(); + String code = captcha.getCode(); + + // 数学验证码,计算表达式结果存储 + if ("math".equals(captchaType)) { + Expression exp = expressionParser.parseExpression(StringUtils.remove(code, "=")); + code = exp.getValue(String.class); + } + RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + return new CaptchaVo(true, uuid, captcha.getImageBase64()); + } + + /** + * 校验图形验证码 + *

【一次性消费】校验通过自动删除缓存,防止重复使用、重放攻击 + * + * @param uuid 前端传递验证码唯一标识 + * @param inputCode 用户输入验证码 + * @return true=验证通过 false=验证失败 + */ + public boolean verifyImageCaptcha(String uuid, String inputCode) { + + return true; + } + + // ====================== 【手机短信验证码】 ====================== + + /** + * 生成手机短信验证码并发送 + * + * @param phoneNumber 手机号 + */ + public void generateSmsCaptcha(String phoneNumber) { + if (!RegexValidator.isMobile(phoneNumber)) { + return; + } + String key = GlobalConstants.CAPTCHA_CODE_KEY + phoneNumber; + String code = RandomUtil.randomNumbers(6); + // 验证码模板id 自行处理 (查数据库或写死均可) + String templateId = ""; + LinkedHashMap map = new LinkedHashMap<>(1); + map.put("code", code); + SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); + + SmsResponse smsResponse; + try { + smsResponse = smsBlend.sendMessage(phoneNumber, templateId, map); + } catch (Exception e) { + log.error("验证码短信发送异常,手机号:{}", phoneNumber, e); + return; + } + if (!smsResponse.isSuccess()) { + log.error("验证码短信发送失败 => {}", smsResponse); + return; + } + // 发送成功才写入缓存 + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + } + + /** + * 校验短信验证码 + *

【一次性消费】校验成功自动删除缓存 + * + * @param phoneNumber 手机号 + * @param inputCode 用户输入验证码 + * @return 是否通过 + */ + public boolean verifySmsCaptcha(String phoneNumber, String inputCode) { + return true; + } + // ====================== 【邮箱验证码】 ====================== + + /** + * 生成邮箱验证码并发送 + * 限流:同一个邮箱60秒最多1次 + * + * @param email 邮箱地址 + */ + @RateLimiter(key = "#email", time = 60, count = 1) + public void generateEmailCaptcha(String email) { + if (!RegexValidator.isEmail(email)) { + return; + } + String key = GlobalConstants.CAPTCHA_CODE_KEY + email; + String code = RandomUtil.randomNumbers(6); + try { + MailBuilder.of().to(email).subject("登录验证码").text("您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。").send(); + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + } catch (Exception e) { + log.error("验证码短信发送异常 => {}", e.getMessage()); + } + } + + /** + * 校验邮箱验证码 + * + * @param inputCode 用户输入 + * @param cacheCode 缓存验证码 + * @return 是否通过 + */ + public boolean verifyEmailCaptcha(String inputCode, String cacheCode) { + return true; + } + + // ====================== 【行为验证码(滑块/点选)】 ====================== + + /** + * 生成行为验证码初始票据 ticket + * 用于前端拉取滑块背景图、滑块图 + * + * @return ticket字符串 + */ + public ApiResponse generateBehaviorCaptchaTicket() { + String type; + int i = ThreadLocalRandom.current().nextInt(0, 4); + if (i == 0) { + type = CaptchaTypeConstant.SLIDER; + } else if (i == 1) { + type = CaptchaTypeConstant.CONCAT; + } else if (i == 2) { + type = CaptchaTypeConstant.ROTATE; + } else { + type = CaptchaTypeConstant.WORD_IMAGE_CLICK; + } + GenerateParam generateParam = new GenerateParam(); + // 要生成的验证码类型 + generateParam.setType(type); + return imageCaptchaApplication.generateCaptcha(generateParam); + } + + + /** + * 行为验证码一次校验(滑块坐标、轨迹校验由第三方SDK/自研逻辑实现) + * 本方法仅做凭证匹配占位,实际行为判定需要额外业务逻辑 + * + * @param ticket 请求票据 + * @param cacheTicket 缓存票据 + * @return 票据是否匹配 + */ + public ApiResponse verifyBehaviorCaptchaFirstStage(String id, ImageCaptchaTrack data) { + ApiResponse response = imageCaptchaApplication.matching(id, data); + if (response.isSuccess()) { + return ApiResponse.ofSuccess(Collections.singletonMap("id", id)); + } + return response; + } + + /** + * 行为验证码二次验证(业务接口调用,例如登录接口) + * + * @param verifyTicket 前端传入二次凭证 + * @param cacheVerifyTicket 服务端缓存凭证 + * @return 验证结果 + */ + public boolean verifyBehaviorCaptchaSecondStage(String verifyTicket, String cacheVerifyTicket) { + return true; + } +} diff --git a/ruoyi-common/ruoyi-common-captcha/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-captcha/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000..ee7d08602 --- /dev/null +++ b/ruoyi-common/ruoyi-common-captcha/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.dromara.common.captcha.config.CaptchaConfig diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java deleted file mode 100644 index 7140db947..000000000 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dromara.common.web.config; - -import org.dromara.common.web.config.properties.CaptchaProperties; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; - -/** - * 验证码配置 - * - * @author Lion Li - */ -@AutoConfiguration -@EnableConfigurationProperties(CaptchaProperties.class) -public class CaptchaConfig { - -} diff --git a/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 7299472a0..1f706e721 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,4 +1,3 @@ -org.dromara.common.web.config.CaptchaConfig org.dromara.common.web.config.FilterConfig org.dromara.common.web.config.I18nConfig org.dromara.common.web.config.ResourcesConfig