mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-31 22:57:19 +08:00 
			
		
		
		
	feat(captcha): 新增行为验证码自动配置
This commit is contained in:
		| @@ -0,0 +1,31 @@ | ||||
| <?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"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|         <groupId>top.charles7c.continew</groupId> | ||||
|         <artifactId>continew-starter-captcha</artifactId> | ||||
|         <version>${revision}</version> | ||||
|     </parent> | ||||
|  | ||||
|     <artifactId>continew-starter-captcha-behavior</artifactId> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>${project.artifactId}</name> | ||||
|     <description>ContiNew Starter 验证码模块 - 行为验证码</description> | ||||
|  | ||||
|     <dependencies> | ||||
|         <!-- AJ-Captcha(行为验证码,包含滑动拼图、文字点选两种方式,UI支持弹出和嵌入两种方式) --> | ||||
|         <dependency> | ||||
|             <groupId>com.anji-plus</groupId> | ||||
|             <artifactId>captcha</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- 缓存模块 - Redisson --> | ||||
|         <dependency> | ||||
|             <groupId>top.charles7c.continew</groupId> | ||||
|             <artifactId>continew-starter-cache-redisson</artifactId> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| </project> | ||||
| @@ -0,0 +1,143 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.captcha.behavior.autoconfigure; | ||||
|  | ||||
| import cn.hutool.core.codec.Base64; | ||||
| import cn.hutool.core.io.FileUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import com.anji.captcha.model.common.Const; | ||||
| import com.anji.captcha.service.CaptchaService; | ||||
| import com.anji.captcha.service.impl.CaptchaServiceFactory; | ||||
| import com.anji.captcha.util.ImageUtils; | ||||
| import jakarta.annotation.PostConstruct; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.boot.autoconfigure.AutoConfiguration; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.Import; | ||||
| import org.springframework.core.io.Resource; | ||||
| import org.springframework.core.io.support.PathMatchingResourcePatternResolver; | ||||
| import org.springframework.core.io.support.ResourcePatternResolver; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.Properties; | ||||
|  | ||||
| /** | ||||
|  * 行为验证码自动配置 | ||||
|  * | ||||
|  * @author Bull-BCLS | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Slf4j | ||||
| @AutoConfiguration | ||||
| @RequiredArgsConstructor | ||||
| @ConditionalOnProperty(prefix = "continew-starter.captcha.behavior", name = "enabled", havingValue = "true") | ||||
| @EnableConfigurationProperties(BehaviorCaptchaProperties.class) | ||||
| public class BehaviorCaptchaAutoConfiguration { | ||||
|  | ||||
|     private final BehaviorCaptchaProperties properties; | ||||
|  | ||||
|     /** | ||||
|      * 自定义缓存实现配置 | ||||
|      */ | ||||
|     @Configuration | ||||
|     @Import({BehaviorCaptchaCacheConfiguration.Redis.class, BehaviorCaptchaCacheConfiguration.Local.class, BehaviorCaptchaCacheConfiguration.Custom.class}) | ||||
|     protected static class BehaviorCaptchaCacheAutoConfiguration { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 行为验证码服务接口 | ||||
|      */ | ||||
|     @Bean | ||||
|     @ConditionalOnMissingBean | ||||
|     public CaptchaService captchaService() { | ||||
|         Properties config = new Properties(); | ||||
|         config.put(Const.CAPTCHA_CACHETYPE, properties.getCacheType().name().toLowerCase()); | ||||
|         config.put(Const.CAPTCHA_WATER_MARK, properties.getWaterMark()); | ||||
|         config.put(Const.CAPTCHA_FONT_TYPE, properties.getFontType()); | ||||
|         config.put(Const.CAPTCHA_TYPE, properties.getType().getCodeValue()); | ||||
|         config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, properties.getInterferenceOptions()); | ||||
|         config.put(Const.ORIGINAL_PATH_JIGSAW, StrUtil.emptyIfNull(properties.getJigsawBaseMapPath())); | ||||
|         config.put(Const.ORIGINAL_PATH_PIC_CLICK, StrUtil.emptyIfNull(properties.getPicClickBaseMapPath())); | ||||
|         config.put(Const.CAPTCHA_SLIP_OFFSET, properties.getSlipOffset()); | ||||
|         config.put(Const.CAPTCHA_AES_STATUS, String.valueOf(properties.getEnableAES())); | ||||
|         config.put(Const.CAPTCHA_WATER_FONT, properties.getWaterFont()); | ||||
|         config.put(Const.CAPTCHA_CACAHE_MAX_NUMBER, properties.getCacheNumber()); | ||||
|         config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, properties.getTimingClear()); | ||||
|         config.put(Const.HISTORY_DATA_CLEAR_ENABLE, properties.getHistoryDataClearEnable()); | ||||
|         config.put(Const.REQ_FREQUENCY_LIMIT_ENABLE, properties.getReqFrequencyLimitEnable()); | ||||
|         config.put(Const.REQ_GET_LOCK_LIMIT, properties.getReqGetLockLimit()); | ||||
|         config.put(Const.REQ_GET_LOCK_SECONDS, properties.getReqGetLockSeconds()); | ||||
|         config.put(Const.REQ_GET_MINUTE_LIMIT, properties.getReqGetMinuteLimit()); | ||||
|         config.put(Const.REQ_CHECK_MINUTE_LIMIT, properties.getReqCheckMinuteLimit()); | ||||
|         config.put(Const.REQ_VALIDATE_MINUTE_LIMIT, properties.getReqVerifyMinuteLimit()); | ||||
|         config.put(Const.CAPTCHA_FONT_SIZE, properties.getFontSize()); | ||||
|         config.put(Const.CAPTCHA_FONT_STYLE, properties.getFontStyle()); | ||||
|         config.put(Const.CAPTCHA_WORD_COUNT, 4); | ||||
|         if (StrUtil.startWith(properties.getJigsawBaseMapPath(), "classpath:") | ||||
|                 || StrUtil.startWith(properties.getPicClickBaseMapPath(), "classpath:")) { | ||||
|             // 自定义 resources 目录下初始化底图 | ||||
|             config.put(Const.CAPTCHA_INIT_ORIGINAL, true); | ||||
|             initializeBaseMap(properties.getJigsawBaseMapPath(), properties.getPicClickBaseMapPath()); | ||||
|         } | ||||
|         return CaptchaServiceFactory.getInstance(config); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 初始化 行为/点选 验证码底图 | ||||
|      * | ||||
|      * @param jigsaw   行为验证码底图路径 | ||||
|      * @param picClick 点选验证码底图路径 | ||||
|      */ | ||||
|     private static void initializeBaseMap(String jigsaw, String picClick) { | ||||
|         ImageUtils.cacheBootImage(getResourcesImagesFile(jigsaw + "/original/*.png"), | ||||
|                 getResourcesImagesFile(jigsaw + "/slidingBlock/*.png"), | ||||
|                 getResourcesImagesFile(picClick + "/*.png")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取图片 | ||||
|      * | ||||
|      * @param path 图片路径 | ||||
|      * @return key:图片文件名称;value:图片 | ||||
|      */ | ||||
|     private static Map<String, String> getResourcesImagesFile(String path) { | ||||
|         Map<String, String> imgMap = new HashMap<>(); | ||||
|         ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); | ||||
|         try { | ||||
|             Resource[] resources = resolver.getResources(path); | ||||
|             for (Resource resource : resources) { | ||||
|                 String imageName = resource.getFilename(); | ||||
|                 byte[] imageValue = FileUtil.readBytes(resource.getFile()); | ||||
|                 imgMap.put(imageName, Base64.encode(imageValue)); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             log.error("读取路径为 [{}] 下的图片文件失败", path, e); | ||||
|         } | ||||
|         return imgMap; | ||||
|     } | ||||
|  | ||||
|     @PostConstruct | ||||
|     public void postConstruct() { | ||||
|         log.info("[ContiNew Starter] - Auto Configuration 'Behavior Captcha' completed initialization."); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.captcha.behavior.autoconfigure; | ||||
|  | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import com.anji.captcha.service.CaptchaCacheService; | ||||
| import com.anji.captcha.service.impl.CaptchaCacheServiceMemImpl; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.redisson.client.RedisClient; | ||||
| import org.springframework.boot.autoconfigure.AutoConfigureBefore; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import top.charles7c.continew.starter.cache.redisson.autoconfigure.RedissonAutoConfiguration; | ||||
| import top.charles7c.continew.starter.captcha.behavior.impl.BehaviorCaptchaCacheServiceImpl; | ||||
|  | ||||
| /** | ||||
|  * 行为验证码缓存配置 | ||||
|  * | ||||
|  * @author Bull-BCLS | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Slf4j | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| abstract class BehaviorCaptchaCacheConfiguration { | ||||
|  | ||||
|     /** | ||||
|      * 自定义缓存实现类-Redis | ||||
|      */ | ||||
|     @ConditionalOnClass(RedisClient.class) | ||||
|     @ConditionalOnMissingBean(CaptchaCacheService.class) | ||||
|     @AutoConfigureBefore(RedissonAutoConfiguration.class) | ||||
|     @ConditionalOnProperty(name = "continew-starter.captcha.behavior.cache-type", havingValue = "redis") | ||||
|     static class Redis { | ||||
|         static { | ||||
|             log.debug("[ContiNew Starter] - Auto Configuration 'Behavior-CaptchaCache-Redis' completed initialization."); | ||||
|         } | ||||
|  | ||||
|         @Bean | ||||
|         public CaptchaCacheService captchaCacheService() { | ||||
|             return new BehaviorCaptchaCacheServiceImpl(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 自定义缓存实现类-内存 | ||||
|      */ | ||||
|     @ConditionalOnMissingBean(CaptchaCacheService.class) | ||||
|     @ConditionalOnProperty(name = "continew-starter.captcha.behavior.cache-type", havingValue = "local") | ||||
|     static class Local { | ||||
|         static { | ||||
|             log.debug("[ContiNew Starter] - Auto Configuration 'Behavior-CaptchaCache-Local' completed initialization."); | ||||
|         } | ||||
|  | ||||
|         @Bean | ||||
|         public CaptchaCacheService captchaCacheService() { | ||||
|             return new CaptchaCacheServiceMemImpl(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 自定义缓存实现类-自定义 | ||||
|      */ | ||||
|     @ConditionalOnMissingBean(CaptchaCacheService.class) | ||||
|     @ConditionalOnProperty(name = "continew-starter.captcha.behavior.cache-type", havingValue = "custom") | ||||
|     static class Custom { | ||||
|         static { | ||||
|             log.debug("[ContiNew Starter] - Auto Configuration 'Behavior-CaptchaCache-Custom' completed initialization."); | ||||
|         } | ||||
|  | ||||
|         @Bean | ||||
|         public CaptchaCacheService captchaCacheService(BehaviorCaptchaProperties properties) { | ||||
|             return ReflectUtil.newInstance(properties.getCacheImpl()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,151 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.captcha.behavior.autoconfigure; | ||||
|  | ||||
| import com.anji.captcha.model.common.CaptchaTypeEnum; | ||||
| import com.anji.captcha.service.CaptchaCacheService; | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import top.charles7c.continew.starter.captcha.behavior.enums.StorageType; | ||||
|  | ||||
| import java.awt.*; | ||||
|  | ||||
| /** | ||||
|  * 行为验证码配置属性 | ||||
|  * | ||||
|  * @author Bull-BCLS | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Data | ||||
| @ConfigurationProperties(prefix = "continew-starter.captcha.behavior") | ||||
| public class BehaviorCaptchaProperties { | ||||
|  | ||||
|     /** | ||||
|      * 是否启用行为验证码 | ||||
|      */ | ||||
|     private boolean enabled = false; | ||||
|  | ||||
|     /** | ||||
|      * 是否开启 AES 坐标加密(默认:true) | ||||
|      */ | ||||
|     private Boolean enableAES = true; | ||||
|  | ||||
|     /** | ||||
|      * 验证码类型(默认:滑动验证码) | ||||
|      */ | ||||
|     private CaptchaTypeEnum type = CaptchaTypeEnum.BLOCKPUZZLE; | ||||
|  | ||||
|     /** | ||||
|      * 缓存类型(默认:LOCAL 内存) | ||||
|      */ | ||||
|     private StorageType cacheType = StorageType.LOCAL; | ||||
|  | ||||
|     /** | ||||
|      * 自定义缓存类型(当 cacheType 为 CUSTOM 时必填) | ||||
|      */ | ||||
|     private Class<? extends CaptchaCacheService> cacheImpl; | ||||
|  | ||||
|     /** | ||||
|      * 滑动拼图底图路径(为空则使用默认底图)(路径下需要有两个文件夹,分别为 original(存放底图)slidingBlock(存放滑块)) | ||||
|      */ | ||||
|     private String jigsawBaseMapPath; | ||||
|  | ||||
|     /** | ||||
|      * 校验滑动拼图允许误差偏移量(默认:5像素) | ||||
|      */ | ||||
|     private String slipOffset = "5"; | ||||
|  | ||||
|     /** | ||||
|      * 点选文字底图路径(为空则使用默认底图) | ||||
|      */ | ||||
|     private String picClickBaseMapPath; | ||||
|  | ||||
|     /** | ||||
|      * 点选文字验证码的文字字体(默认:文泉驿正黑) | ||||
|      */ | ||||
|     private String fontType = "WenQuanZhengHei.ttf"; | ||||
|  | ||||
|     /** | ||||
|      * 历史数据清除开关(0:关闭;1:开启) | ||||
|      */ | ||||
|     private Integer historyDataClearEnable = 0; | ||||
|  | ||||
|     /** | ||||
|      * 一分钟内接口请求次数限制开关(0:关闭;1:开启) | ||||
|      */ | ||||
|     private Integer reqFrequencyLimitEnable = 0; | ||||
|  | ||||
|     /** | ||||
|      * 一分钟内验证码最多失败次数限制(默认:5次) | ||||
|      */ | ||||
|     private int reqGetLockLimit = 5; | ||||
|  | ||||
|     /** | ||||
|      * 一分钟内验证码最多失败次数限制达标后锁定时间(默认:300秒) | ||||
|      */ | ||||
|     private int reqGetLockSeconds = 300; | ||||
|  | ||||
|     /** | ||||
|      * 获取验证码接口一分钟内请求次数限制(默认:100次) | ||||
|      */ | ||||
|     private int reqGetMinuteLimit = 100; | ||||
|  | ||||
|     /** | ||||
|      * 校验检验码接口一分内请求次数限制(默认:100次) | ||||
|      */ | ||||
|     private int reqCheckMinuteLimit = 100; | ||||
|  | ||||
|     /** | ||||
|      * 二次校验检验码接口一分钟内请求次数限制(默认:100次) | ||||
|      */ | ||||
|     private int reqVerifyMinuteLimit = 100; | ||||
|  | ||||
|     /** | ||||
|      * local缓存的阈值(默认:1000个) | ||||
|      */ | ||||
|     private String cacheNumber = "1000"; | ||||
|  | ||||
|     /** | ||||
|      * 定时清理过期local缓存(默认:180秒) | ||||
|      */ | ||||
|     private String timingClear = "180"; | ||||
|  | ||||
|     /** | ||||
|      * 右下角水印文字 | ||||
|      */ | ||||
|     private String waterMark = "我的水印"; | ||||
|  | ||||
|     /** | ||||
|      * 右下角水印字体(默认:文泉驿正黑) | ||||
|      */ | ||||
|     private String waterFont = "WenQuanZhengHei.ttf"; | ||||
|  | ||||
|     /** | ||||
|      * 滑块干扰项(默认:0) | ||||
|      */ | ||||
|     private String interferenceOptions = "0"; | ||||
|  | ||||
|     /** | ||||
|      * 点选字体样式(默认:BOLD) | ||||
|      */ | ||||
|     private int fontStyle = Font.BOLD; | ||||
|  | ||||
|     /** | ||||
|      * 点选字体大小(默认:25) | ||||
|      */ | ||||
|     private int fontSize = 25; | ||||
| } | ||||
| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.captcha.behavior.enums; | ||||
|  | ||||
| import lombok.Getter; | ||||
|  | ||||
| /** | ||||
|  * 缓存类型枚举 | ||||
|  * | ||||
|  * @author Bull-BCLS | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| @Getter | ||||
| public enum StorageType { | ||||
|  | ||||
|     /** | ||||
|      * 内存 | ||||
|      */ | ||||
|     LOCAL, | ||||
|  | ||||
|     /** | ||||
|      * Redis | ||||
|      */ | ||||
|     REDIS, | ||||
|  | ||||
|     /** | ||||
|      * 自定义 | ||||
|      */ | ||||
|     CUSTOM, | ||||
| } | ||||
| @@ -0,0 +1,56 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.charles7c.continew.starter.captcha.behavior.impl; | ||||
|  | ||||
| import com.anji.captcha.service.CaptchaCacheService; | ||||
| import top.charles7c.continew.starter.cache.redisson.util.RedisUtils; | ||||
| import top.charles7c.continew.starter.captcha.behavior.enums.StorageType; | ||||
|  | ||||
| import java.time.Duration; | ||||
|  | ||||
| /** | ||||
|  * 行为验证码 Redis 缓存实现 | ||||
|  * | ||||
|  * @author Bull-BCLS | ||||
|  * @since 1.1.0 | ||||
|  */ | ||||
| public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService { | ||||
|     @Override | ||||
|     public void set(String key, String value, long expiresInSeconds) { | ||||
|         RedisUtils.set(key, value, Duration.ofSeconds(expiresInSeconds)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean exists(String key) { | ||||
|         return RedisUtils.hasKey(key); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void delete(String key) { | ||||
|         RedisUtils.delete(key); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String get(String key) { | ||||
|         return RedisUtils.get(key); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String type() { | ||||
|         return StorageType.REDIS.name().toLowerCase(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1 @@ | ||||
| top.charles7c.continew.starter.captcha.behavior.autoconfigure.BehaviorCaptchaAutoConfiguration | ||||
| @@ -21,7 +21,7 @@ import cn.hutool.core.util.StrUtil; | ||||
| import com.wf.captcha.base.Captcha; | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import top.charles7c.continew.starter.captcha.graphic.enums.GraphicCaptchaTypeEnum; | ||||
| import top.charles7c.continew.starter.captcha.graphic.enums.GraphicCaptchaType; | ||||
|  | ||||
| import java.awt.*; | ||||
|  | ||||
| @@ -43,7 +43,7 @@ public class GraphicCaptchaProperties { | ||||
|     /** | ||||
|      * 类型 | ||||
|      */ | ||||
|     private GraphicCaptchaTypeEnum type; | ||||
|     private GraphicCaptchaType type; | ||||
|  | ||||
|     /** | ||||
|      * 内容长度 | ||||
|   | ||||
| @@ -29,7 +29,7 @@ import lombok.RequiredArgsConstructor; | ||||
|  */ | ||||
| @Getter | ||||
| @RequiredArgsConstructor | ||||
| public enum GraphicCaptchaTypeEnum { | ||||
| public enum GraphicCaptchaType { | ||||
| 
 | ||||
|     /** | ||||
|      * 算术 | ||||
| @@ -17,6 +17,7 @@ | ||||
|  | ||||
|     <modules> | ||||
|         <module>continew-starter-captcha-graphic</module> | ||||
|         <module>continew-starter-captcha-behavior</module> | ||||
|     </modules> | ||||
|  | ||||
|     <dependencies> | ||||
|   | ||||
| @@ -62,6 +62,7 @@ | ||||
|         <p6spy.version>3.9.1</p6spy.version> | ||||
|         <redisson.version>3.25.2</redisson.version> | ||||
|         <sms4j.version>3.0.4</sms4j.version> | ||||
|         <aj-captcha.version>1.3.0</aj-captcha.version> | ||||
|         <easy-captcha.version>1.6.2</easy-captcha.version> | ||||
|         <easy-excel.version>3.3.3</easy-excel.version> | ||||
|         <knife4j.version>4.4.0</knife4j.version> | ||||
| @@ -149,6 +150,13 @@ | ||||
|                 <version>${sms4j.version}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- AJ-Captcha(行为验证码,包含滑动拼图、文字点选两种方式,UI支持弹出和嵌入两种方式) --> | ||||
|             <dependency> | ||||
|                 <groupId>com.anji-plus</groupId> | ||||
|                 <artifactId>captcha</artifactId> | ||||
|                 <version>${aj-captcha.version}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- Easy Captcha(Java 图形验证码,支持 gif、中文、算术等类型,可用于 Java Web、JavaSE 等项目) --> | ||||
|             <dependency> | ||||
|                 <groupId>com.github.whvcse</groupId> | ||||
| @@ -243,6 +251,13 @@ | ||||
|                 <version>${revision}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- 验证码模块 - 行为验证码 --> | ||||
|             <dependency> | ||||
|                 <groupId>top.charles7c.continew</groupId> | ||||
|                 <artifactId>continew-starter-captcha-behavior</artifactId> | ||||
|                 <version>${revision}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- 验证码模块 - 图形验证码 --> | ||||
|             <dependency> | ||||
|                 <groupId>top.charles7c.continew</groupId> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Bull-BCLS
					Bull-BCLS