fix(captcha): 修复行为验证码接口请求次数限制

This commit is contained in:
Yoofff
2024-05-20 20:53:38 +08:00
parent e3de3b6721
commit 62121b78ec
5 changed files with 67 additions and 52 deletions

View File

@@ -31,12 +31,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver;
import top.continew.starter.captcha.behavior.autoconfigure.cache.BehaviorCaptchaCacheConfiguration;
import top.continew.starter.core.constant.PropertiesConstants; import top.continew.starter.core.constant.PropertiesConstants;
import java.util.HashMap; import java.util.HashMap;
@@ -61,18 +59,11 @@ public class BehaviorCaptchaAutoConfiguration {
this.properties = properties; this.properties = properties;
} }
/**
* 自定义缓存实现配置
*/
@Configuration
@Import({BehaviorCaptchaCacheConfiguration.Default.class, BehaviorCaptchaCacheConfiguration.Redis.class,
BehaviorCaptchaCacheConfiguration.Custom.class})
protected static class BehaviorCaptchaCacheAutoConfiguration {}
/** /**
* 行为验证码服务接口 * 行为验证码服务接口
*/ */
@Bean @Bean
@DependsOn("captchaCacheService")
@ConditionalOnMissingBean @ConditionalOnMissingBean
public CaptchaService captchaService() { public CaptchaService captchaService() {
Properties config = new Properties(); Properties config = new Properties();

View File

@@ -16,6 +16,7 @@
package top.continew.starter.captcha.behavior.autoconfigure; package top.continew.starter.captcha.behavior.autoconfigure;
import cn.hutool.core.convert.Convert;
import com.anji.captcha.model.common.CaptchaTypeEnum; import com.anji.captcha.model.common.CaptchaTypeEnum;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import top.continew.starter.captcha.behavior.enums.StorageType; import top.continew.starter.captcha.behavior.enums.StorageType;
@@ -75,37 +76,37 @@ public class BehaviorCaptchaProperties {
/** /**
* 历史数据清除开关0关闭1开启 * 历史数据清除开关0关闭1开启
*/ */
private Integer historyDataClearEnable = 0; private String historyDataClearEnable = "0";
/** /**
* 一分钟内接口请求次数限制开关0关闭1开启 * 一分钟内接口请求次数限制开关0关闭1开启
*/ */
private Integer reqFrequencyLimitEnable = 0; private String reqFrequencyLimitEnable = "0";
/** /**
* 一分钟内验证码最多失败次数限制默认5次 * 一分钟内验证码最多失败次数限制默认5次
*/ */
private int reqGetLockLimit = 5; private String reqGetLockLimit = "5";
/** /**
* 一分钟内验证码最多失败次数限制达标后锁定时间默认300秒 * 一分钟内验证码最多失败次数限制达标后锁定时间默认300秒
*/ */
private int reqGetLockSeconds = 300; private String reqGetLockSeconds = "300";
/** /**
* 获取验证码接口一分钟内请求次数限制默认100次 * 获取验证码接口一分钟内请求次数限制默认100次
*/ */
private int reqGetMinuteLimit = 100; private String reqGetMinuteLimit = "100";
/** /**
* 校验检验码接口一分内请求次数限制默认100次 * 校验检验码接口一分内请求次数限制默认100次
*/ */
private int reqCheckMinuteLimit = 100; private String reqCheckMinuteLimit = "100";
/** /**
* 二次校验检验码接口一分钟内请求次数限制默认100次 * 二次校验检验码接口一分钟内请求次数限制默认100次
*/ */
private int reqVerifyMinuteLimit = 100; private String reqVerifyMinuteLimit = "100";
/** /**
* local缓存的阈值默认1000个 * local缓存的阈值默认1000个
@@ -135,12 +136,12 @@ public class BehaviorCaptchaProperties {
/** /**
* 点选字体样式默认BOLD * 点选字体样式默认BOLD
*/ */
private int fontStyle = Font.BOLD; private String fontStyle = Convert.toStr(Font.BOLD);
/** /**
* 点选字体大小默认25 * 点选字体大小默认25
*/ */
private int fontSize = 25; private String fontSize = "25";
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
@@ -206,59 +207,59 @@ public class BehaviorCaptchaProperties {
this.fontType = fontType; this.fontType = fontType;
} }
public Integer getHistoryDataClearEnable() { public String getHistoryDataClearEnable() {
return historyDataClearEnable; return historyDataClearEnable;
} }
public void setHistoryDataClearEnable(Integer historyDataClearEnable) { public void setHistoryDataClearEnable(String historyDataClearEnable) {
this.historyDataClearEnable = historyDataClearEnable; this.historyDataClearEnable = historyDataClearEnable;
} }
public Integer getReqFrequencyLimitEnable() { public String getReqFrequencyLimitEnable() {
return reqFrequencyLimitEnable; return reqFrequencyLimitEnable;
} }
public void setReqFrequencyLimitEnable(Integer reqFrequencyLimitEnable) { public void setReqFrequencyLimitEnable(String reqFrequencyLimitEnable) {
this.reqFrequencyLimitEnable = reqFrequencyLimitEnable; this.reqFrequencyLimitEnable = reqFrequencyLimitEnable;
} }
public int getReqGetLockLimit() { public String getReqGetLockLimit() {
return reqGetLockLimit; return reqGetLockLimit;
} }
public void setReqGetLockLimit(int reqGetLockLimit) { public void setReqGetLockLimit(String reqGetLockLimit) {
this.reqGetLockLimit = reqGetLockLimit; this.reqGetLockLimit = reqGetLockLimit;
} }
public int getReqGetLockSeconds() { public String getReqGetLockSeconds() {
return reqGetLockSeconds; return reqGetLockSeconds;
} }
public void setReqGetLockSeconds(int reqGetLockSeconds) { public void setReqGetLockSeconds(String reqGetLockSeconds) {
this.reqGetLockSeconds = reqGetLockSeconds; this.reqGetLockSeconds = reqGetLockSeconds;
} }
public int getReqGetMinuteLimit() { public String getReqGetMinuteLimit() {
return reqGetMinuteLimit; return reqGetMinuteLimit;
} }
public void setReqGetMinuteLimit(int reqGetMinuteLimit) { public void setReqGetMinuteLimit(String reqGetMinuteLimit) {
this.reqGetMinuteLimit = reqGetMinuteLimit; this.reqGetMinuteLimit = reqGetMinuteLimit;
} }
public int getReqCheckMinuteLimit() { public String getReqCheckMinuteLimit() {
return reqCheckMinuteLimit; return reqCheckMinuteLimit;
} }
public void setReqCheckMinuteLimit(int reqCheckMinuteLimit) { public void setReqCheckMinuteLimit(String reqCheckMinuteLimit) {
this.reqCheckMinuteLimit = reqCheckMinuteLimit; this.reqCheckMinuteLimit = reqCheckMinuteLimit;
} }
public int getReqVerifyMinuteLimit() { public String getReqVerifyMinuteLimit() {
return reqVerifyMinuteLimit; return reqVerifyMinuteLimit;
} }
public void setReqVerifyMinuteLimit(int reqVerifyMinuteLimit) { public void setReqVerifyMinuteLimit(String reqVerifyMinuteLimit) {
this.reqVerifyMinuteLimit = reqVerifyMinuteLimit; this.reqVerifyMinuteLimit = reqVerifyMinuteLimit;
} }
@@ -302,19 +303,19 @@ public class BehaviorCaptchaProperties {
this.interferenceOptions = interferenceOptions; this.interferenceOptions = interferenceOptions;
} }
public int getFontStyle() { public String getFontStyle() {
return fontStyle; return fontStyle;
} }
public void setFontStyle(int fontStyle) { public void setFontStyle(String fontStyle) {
this.fontStyle = fontStyle; this.fontStyle = fontStyle;
} }
public int getFontSize() { public String getFontSize() {
return fontSize; return fontSize;
} }
public void setFontSize(int fontSize) { public void setFontSize(String fontSize) {
this.fontSize = fontSize; this.fontSize = fontSize;
} }
} }

View File

@@ -25,7 +25,7 @@ import org.redisson.client.RedisClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -36,29 +36,35 @@ import top.continew.starter.captcha.behavior.enums.StorageType;
import top.continew.starter.core.constant.PropertiesConstants; import top.continew.starter.core.constant.PropertiesConstants;
/** /**
* 行为验证码缓存配置 * 行为验证码缓存自动配置
* *
* @author Bull-BCLS * @author Bull-BCLS
* @author Charles7c * @author Charles7c
* @since 1.1.0 * @since 1.1.0
*/ */
public class BehaviorCaptchaCacheConfiguration { @AutoConfiguration()
public class BehaviorCaptchaCacheAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(BehaviorCaptchaCacheConfiguration.class); private static final Logger log = LoggerFactory.getLogger(BehaviorCaptchaCacheAutoConfiguration.class);
private BehaviorCaptchaCacheConfiguration() { private BehaviorCaptchaCacheAutoConfiguration() {
} }
/** /**
* 自定义缓存实现-默认内存 * 自定义缓存实现-默认内存
*/ */
@AutoConfiguration
@ConditionalOnMissingBean(CaptchaCacheService.class) @ConditionalOnMissingBean(CaptchaCacheService.class)
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "default", matchIfMissing = true) @ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "default", matchIfMissing = true)
public static class Default { public static class Default {
@Bean
public CaptchaCacheService captchaCacheService() {
return new CaptchaCacheServiceMemImpl();
}
@PostConstruct @PostConstruct
public void postConstruct() { public void postConstruct() {
CaptchaServiceFactory.cacheService.put(StorageType.DEFAULT.name() CaptchaServiceFactory.cacheService.put(StorageType.DEFAULT.name().toLowerCase(), captchaCacheService());
.toLowerCase(), new CaptchaCacheServiceMemImpl());
log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Default' completed initialization."); log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Default' completed initialization.");
} }
} }
@@ -66,15 +72,19 @@ public class BehaviorCaptchaCacheConfiguration {
/** /**
* 自定义缓存实现-Redis * 自定义缓存实现-Redis
*/ */
@ConditionalOnMissingBean(CaptchaCacheService.class) @AutoConfiguration(before = RedissonAutoConfiguration.class)
@ConditionalOnClass(RedisClient.class) @ConditionalOnClass(RedisClient.class)
@AutoConfigureBefore(RedissonAutoConfiguration.class) @ConditionalOnMissingBean(CaptchaCacheService.class)
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "redis") @ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "redis")
public static class Redis { public static class Redis {
@Bean
public CaptchaCacheService captchaCacheService() {
return new BehaviorCaptchaCacheServiceImpl();
}
@PostConstruct @PostConstruct
public void postConstruct() { public void postConstruct() {
CaptchaServiceFactory.cacheService.put(StorageType.REDIS.name() CaptchaServiceFactory.cacheService.put(StorageType.REDIS.name().toLowerCase(), captchaCacheService());
.toLowerCase(), new BehaviorCaptchaCacheServiceImpl());
log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Redis' completed initialization."); log.debug("[ContiNew Starter] - Auto Configuration 'Captcha-Behavior-Cache-Redis' completed initialization.");
} }
} }
@@ -82,6 +92,7 @@ public class BehaviorCaptchaCacheConfiguration {
/** /**
* 自定义缓存实现 * 自定义缓存实现
*/ */
@AutoConfiguration
@ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "custom") @ConditionalOnProperty(name = PropertiesConstants.CAPTCHA_BEHAVIOR + ".cache-type", havingValue = "custom")
public static class Custom { public static class Custom {
@Bean @Bean

View File

@@ -16,6 +16,8 @@
package top.continew.starter.captcha.behavior.autoconfigure.cache; package top.continew.starter.captcha.behavior.autoconfigure.cache;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import com.anji.captcha.service.CaptchaCacheService; import com.anji.captcha.service.CaptchaCacheService;
import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.captcha.behavior.enums.StorageType; import top.continew.starter.captcha.behavior.enums.StorageType;
@@ -31,7 +33,11 @@ import java.time.Duration;
public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService { public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService {
@Override @Override
public void set(String key, String value, long expiresInSeconds) { public void set(String key, String value, long expiresInSeconds) {
RedisUtils.set(key, value, Duration.ofSeconds(expiresInSeconds)); if (NumberUtil.isNumber(value)) {
RedisUtils.set(key, Convert.toInt(value), Duration.ofSeconds(expiresInSeconds));
} else {
RedisUtils.set(key, value, Duration.ofSeconds(expiresInSeconds));
}
} }
@Override @Override
@@ -46,11 +52,16 @@ public class BehaviorCaptchaCacheServiceImpl implements CaptchaCacheService {
@Override @Override
public String get(String key) { public String get(String key) {
return RedisUtils.get(key); return Convert.toStr(RedisUtils.get(key));
} }
@Override @Override
public String type() { public String type() {
return StorageType.REDIS.name().toLowerCase(); return StorageType.REDIS.name().toLowerCase();
} }
@Override
public Long increment(String key, long val) {
return RedisUtils.incr(key);
}
} }

View File

@@ -1 +1,2 @@
top.continew.starter.captcha.behavior.autoconfigure.BehaviorCaptchaAutoConfiguration top.continew.starter.captcha.behavior.autoconfigure.BehaviorCaptchaAutoConfiguration
top.continew.starter.captcha.behavior.autoconfigure.cache.BehaviorCaptchaCacheAutoConfiguration