mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 06:04:34 +08:00
solon插件暂时无人维护,先考虑单独搬迁项目到另一个仓库
This commit is contained in:
@@ -12,11 +12,10 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module>tianai-captcha</module>
|
<module>tianai-captcha</module>
|
||||||
<module>tianai-captcha-springboot-starter</module>
|
<module>tianai-captcha-springboot-starter</module>
|
||||||
<module>tianai-captcha-solon-plugin</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>1.5.4</revision>
|
<revision>1.5.5</revision>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<!-- 打包跳过单元测试 -->
|
<!-- 打包跳过单元测试 -->
|
||||||
<skipTests>true</skipTests>
|
<skipTests>true</skipTests>
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
<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/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>cloud.tianai.captcha</groupId>
|
|
||||||
<artifactId>tianai-captcha-parent</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>tianai-captcha-solon-plugin</artifactId>
|
|
||||||
<name>tianai-captcha-solon-plugin</name>
|
|
||||||
<description>行为验证码的solon插件</description>
|
|
||||||
<url>https://gitee.com/tianai/tianai-captcha-solon-plugin</url>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<solon.version>3.5.2</solon.version>
|
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
|
|
||||||
<java.version>1.8</java.version>
|
|
||||||
<!-- 打包跳过单元测试 -->
|
|
||||||
<skipTests>true</skipTests>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
|
||||||
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.noear</groupId>
|
|
||||||
<artifactId>solon</artifactId>
|
|
||||||
<version>${solon.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.noear</groupId>
|
|
||||||
<artifactId>solon-web</artifactId>
|
|
||||||
<version>${solon.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cloud.tianai.captcha</groupId>
|
|
||||||
<artifactId>tianai-captcha</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>8</source>
|
|
||||||
<target>8</target>
|
|
||||||
<compilerArgument>-parameters</compilerArgument>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon;
|
|
||||||
|
|
||||||
import cloud.tianai.captcha.solon.config.ImageCaptchaAutoConfiguration;
|
|
||||||
import cloud.tianai.captcha.solon.properties.CaptchaProperties;
|
|
||||||
import org.noear.solon.core.AppContext;
|
|
||||||
import org.noear.solon.core.Plugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插件启动类
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
public class XPluginImp implements Plugin {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(AppContext context) {
|
|
||||||
context.beanMake(CaptchaProperties.class);
|
|
||||||
context.beanMake(ImageCaptchaAutoConfiguration.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-95
@@ -1,95 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.config;
|
|
||||||
|
|
||||||
import cloud.tianai.captcha.application.ImageCaptchaApplication;
|
|
||||||
import cloud.tianai.captcha.application.TACBuilder;
|
|
||||||
import cloud.tianai.captcha.cache.CacheStore;
|
|
||||||
import cloud.tianai.captcha.cache.impl.LocalCacheStore;
|
|
||||||
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
|
||||||
import cloud.tianai.captcha.solon.plugins.secondary.SecondaryVerificationApplication;
|
|
||||||
import cloud.tianai.captcha.solon.properties.CaptchaProperties;
|
|
||||||
import cloud.tianai.captcha.solon.service.CaptchaRedisCacheService;
|
|
||||||
import org.noear.solon.annotation.Bean;
|
|
||||||
import org.noear.solon.annotation.Configuration;
|
|
||||||
import org.noear.solon.annotation.Inject;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class ImageCaptchaAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ImageCaptchaApplication imageCaptchaApplication(CaptchaProperties captchaProperties, @Inject(required = false) CaptchaRedisCacheService cacheService) {
|
|
||||||
TACBuilder tacBuilder = TACBuilder.builder();
|
|
||||||
tacBuilder.addDefaultTemplate();
|
|
||||||
tacBuilder.expire("default", captchaProperties.getExpire());
|
|
||||||
tacBuilder.prefix(captchaProperties.getPrefix());
|
|
||||||
// 注入背景图资源
|
|
||||||
if (captchaProperties.getResources().getAuto()) {
|
|
||||||
String[] split = captchaProperties.getResources().getAutoType().split(",");
|
|
||||||
List<String> wordImageClickList = captchaProperties.getResources().getImages();
|
|
||||||
for (String type : split) {
|
|
||||||
for (String path : wordImageClickList) {
|
|
||||||
tacBuilder.addResource(type, new Resource("classpath", path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
List<String> wordImageClickList = captchaProperties.getResources().getWORD_IMAGE_CLICK();
|
|
||||||
if (!wordImageClickList.isEmpty()) {
|
|
||||||
for (String path : wordImageClickList) {
|
|
||||||
tacBuilder.addResource("WORD_IMAGE_CLICK", new Resource("classpath", path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<String> concatList = captchaProperties.getResources().getCONCAT();
|
|
||||||
if (!concatList.isEmpty()) {
|
|
||||||
for (String path : concatList) {
|
|
||||||
tacBuilder.addResource("CONCAT", new Resource("classpath", path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<String> sliderList = captchaProperties.getResources().getSLIDER();
|
|
||||||
if (!sliderList.isEmpty()) {
|
|
||||||
for (String path : sliderList) {
|
|
||||||
tacBuilder.addResource("SLIDER", new Resource("classpath", path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<String> rotateList = captchaProperties.getResources().getROTATE();
|
|
||||||
if (!rotateList.isEmpty()) {
|
|
||||||
for (String path : rotateList) {
|
|
||||||
tacBuilder.addResource("ROTATE", new Resource("classpath", path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注入字体包
|
|
||||||
if (null != captchaProperties.getFontPath()) {
|
|
||||||
List<String> fontPathList = captchaProperties.getFontPath();
|
|
||||||
if (!fontPathList.isEmpty()) {
|
|
||||||
for (String path : fontPathList) {
|
|
||||||
try {
|
|
||||||
tacBuilder.addFont(new Resource("classpath", path));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("读取字体包失败,path=" + path, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheStore cacheStore = cacheService;
|
|
||||||
// 注入缓存器
|
|
||||||
if (null == cacheStore) {
|
|
||||||
cacheStore = new LocalCacheStore();
|
|
||||||
}
|
|
||||||
tacBuilder.setCacheStore(cacheStore);
|
|
||||||
ImageCaptchaApplication target = tacBuilder.build();
|
|
||||||
|
|
||||||
// 二次验证
|
|
||||||
if (captchaProperties.getSecondary().getEnabled()) {
|
|
||||||
target = new SecondaryVerificationApplication(target, captchaProperties, cacheStore);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-109
@@ -1,109 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.plugins.secondary;
|
|
||||||
|
|
||||||
import cloud.tianai.captcha.application.FilterImageCaptchaApplication;
|
|
||||||
import cloud.tianai.captcha.application.ImageCaptchaApplication;
|
|
||||||
import cloud.tianai.captcha.application.vo.ImageCaptchaVO;
|
|
||||||
import cloud.tianai.captcha.cache.CacheStore;
|
|
||||||
import cloud.tianai.captcha.common.AnyMap;
|
|
||||||
import cloud.tianai.captcha.common.exception.ImageCaptchaException;
|
|
||||||
import cloud.tianai.captcha.common.response.ApiResponse;
|
|
||||||
import cloud.tianai.captcha.solon.properties.CaptchaLimit;
|
|
||||||
import cloud.tianai.captcha.solon.properties.CaptchaProperties;
|
|
||||||
import cloud.tianai.captcha.solon.properties.CaptchaSecondary;
|
|
||||||
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
|
|
||||||
import org.noear.solon.core.handle.Context;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
public class SecondaryVerificationApplication extends FilterImageCaptchaApplication {
|
|
||||||
|
|
||||||
private final CaptchaSecondary prop;
|
|
||||||
private final CaptchaProperties captchaProperties;
|
|
||||||
private final CacheStore redisCacheService;
|
|
||||||
|
|
||||||
public SecondaryVerificationApplication(ImageCaptchaApplication target, CaptchaProperties captchaProperties, CacheStore redisCacheService) {
|
|
||||||
super(target);
|
|
||||||
this.captchaProperties = captchaProperties;
|
|
||||||
this.prop = captchaProperties.getSecondary();
|
|
||||||
this.redisCacheService = redisCacheService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<ImageCaptchaVO> generateCaptcha(String type) {
|
|
||||||
// 检查是否每分钟超过限制
|
|
||||||
CaptchaLimit limit = captchaProperties.getLimit();
|
|
||||||
if (null != limit && limit.getEnable()) {
|
|
||||||
Context current = Context.current();
|
|
||||||
String errLimitKey = getLimitKey(current, "error");
|
|
||||||
Long errLimit = redisCacheService.getLong(errLimitKey);
|
|
||||||
if (null != errLimit && errLimit >= limit.getErrorLimit()) {
|
|
||||||
throw new ImageCaptchaException("验证次数过多,请稍后再试");
|
|
||||||
}
|
|
||||||
String reqLimitKey = getLimitKey(current, "req");
|
|
||||||
Long reqLimit = redisCacheService.getLong(reqLimitKey);
|
|
||||||
if (null != reqLimit && reqLimit >= limit.getReqLimit()) {
|
|
||||||
throw new ImageCaptchaException("获取验证码频繁,请稍后再试");
|
|
||||||
}
|
|
||||||
redisCacheService.incr(reqLimitKey, 1, 60L, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
return super.generateCaptcha(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<?> matching(String id, ImageCaptchaTrack imageCaptchaTrack) {
|
|
||||||
ApiResponse<?> match = super.matching(id, imageCaptchaTrack);
|
|
||||||
if (match.isSuccess()) {
|
|
||||||
// 如果匹配成功, 添加二次验证记录
|
|
||||||
addSecondaryVerification(id + getRemoteId(Context.current()), imageCaptchaTrack);
|
|
||||||
} else {
|
|
||||||
CaptchaLimit limit = captchaProperties.getLimit();
|
|
||||||
if (null != limit && limit.getEnable()) {
|
|
||||||
Context current = Context.current();
|
|
||||||
String limitKey = getLimitKey(current, "error");
|
|
||||||
redisCacheService.incr(limitKey, 1, 60L, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 二次缓存验证
|
|
||||||
* @param id id
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean secondaryVerification(String id) {
|
|
||||||
Map<String, Object> cache = target.getCacheStore().getAndRemoveCache(getKey(id + getRemoteId(Context.current())));
|
|
||||||
return cache != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加二次缓存验证记录
|
|
||||||
* @param id id
|
|
||||||
* @param imageCaptchaTrack sliderCaptchaTrack
|
|
||||||
*/
|
|
||||||
protected void addSecondaryVerification(String id, ImageCaptchaTrack imageCaptchaTrack) {
|
|
||||||
target.getCacheStore().setCache(getKey(id), new AnyMap(), prop.getExpire(), TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getKey(String id) {
|
|
||||||
return prop.getKeyPrefix().concat(":").concat(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getLimitKey(Context ctx, String type) {
|
|
||||||
return prop.getKeyPrefix().concat(":limit:")
|
|
||||||
.concat(type)
|
|
||||||
.concat(":")
|
|
||||||
.concat(getRemoteId(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String getRemoteId(Context ctx) {
|
|
||||||
return ctx.realIp() + ctx.userAgent();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.04
|
|
||||||
*/
|
|
||||||
public class CaptchaLimit {
|
|
||||||
|
|
||||||
private Boolean enable;
|
|
||||||
|
|
||||||
private Long reqLimit;
|
|
||||||
|
|
||||||
private Long errorLimit;
|
|
||||||
|
|
||||||
public Boolean getEnable() {
|
|
||||||
return enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnable(Boolean enable) {
|
|
||||||
this.enable = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getReqLimit() {
|
|
||||||
return reqLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReqLimit(Long reqLimit) {
|
|
||||||
this.reqLimit = reqLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getErrorLimit() {
|
|
||||||
return errorLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrorLimit(Long errorLimit) {
|
|
||||||
this.errorLimit = errorLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.properties;
|
|
||||||
|
|
||||||
import org.noear.solon.annotation.Configuration;
|
|
||||||
import org.noear.solon.annotation.Inject;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
@Inject("${captcha}")
|
|
||||||
@Configuration
|
|
||||||
public class CaptchaProperties {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* redis 前缀
|
|
||||||
*/
|
|
||||||
private String prefix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 有效期
|
|
||||||
*/
|
|
||||||
private Long expire;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字体路径
|
|
||||||
*/
|
|
||||||
private List<String> fontPath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 资源路径
|
|
||||||
*/
|
|
||||||
private CaptchaResource resources;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 二次验证
|
|
||||||
*/
|
|
||||||
private CaptchaSecondary secondary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 每分限流
|
|
||||||
*/
|
|
||||||
private CaptchaLimit limit;
|
|
||||||
|
|
||||||
public String getPrefix() {
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrefix(String prefix) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getExpire() {
|
|
||||||
return expire;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpire(Long expire) {
|
|
||||||
this.expire = expire;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getFontPath() {
|
|
||||||
return fontPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFontPath(List<String> fontPath) {
|
|
||||||
this.fontPath = fontPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CaptchaResource getResources() {
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResources(CaptchaResource resources) {
|
|
||||||
this.resources = resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CaptchaSecondary getSecondary() {
|
|
||||||
return secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecondary(CaptchaSecondary secondary) {
|
|
||||||
this.secondary = secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CaptchaLimit getLimit() {
|
|
||||||
return limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLimit(CaptchaLimit limit) {
|
|
||||||
this.limit = limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.properties;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
public class CaptchaResource {
|
|
||||||
|
|
||||||
private Boolean auto;
|
|
||||||
|
|
||||||
private String autoType;
|
|
||||||
|
|
||||||
private List<String> images;
|
|
||||||
|
|
||||||
private List<String> SLIDER;
|
|
||||||
|
|
||||||
private List<String> WORD_IMAGE_CLICK;
|
|
||||||
|
|
||||||
private List<String> ROTATE;
|
|
||||||
|
|
||||||
private List<String> CONCAT;
|
|
||||||
|
|
||||||
public List<String> getSLIDER() {
|
|
||||||
return SLIDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSLIDER(List<String> SLIDER) {
|
|
||||||
this.SLIDER = SLIDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getWORD_IMAGE_CLICK() {
|
|
||||||
return WORD_IMAGE_CLICK;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWORD_IMAGE_CLICK(List<String> WORD_IMAGE_CLICK) {
|
|
||||||
this.WORD_IMAGE_CLICK = WORD_IMAGE_CLICK;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getROTATE() {
|
|
||||||
return ROTATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setROTATE(List<String> ROTATE) {
|
|
||||||
this.ROTATE = ROTATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getCONCAT() {
|
|
||||||
return CONCAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCONCAT(List<String> CONCAT) {
|
|
||||||
this.CONCAT = CONCAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getAuto() {
|
|
||||||
return auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuto(Boolean auto) {
|
|
||||||
this.auto = auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAutoType() {
|
|
||||||
return autoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoType(String autoType) {
|
|
||||||
this.autoType = autoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getImages() {
|
|
||||||
return images;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImages(List<String> images) {
|
|
||||||
this.images = images;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author XT
|
|
||||||
* @Date 2024.09.03
|
|
||||||
*/
|
|
||||||
public class CaptchaSecondary {
|
|
||||||
|
|
||||||
private Boolean enabled;
|
|
||||||
|
|
||||||
private Long expire;
|
|
||||||
|
|
||||||
private String keyPrefix;
|
|
||||||
|
|
||||||
public Boolean getEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(Boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getExpire() {
|
|
||||||
return expire;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpire(Long expire) {
|
|
||||||
this.expire = expire;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKeyPrefix() {
|
|
||||||
return keyPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyPrefix(String keyPrefix) {
|
|
||||||
this.keyPrefix = keyPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
package cloud.tianai.captcha.solon.service;
|
|
||||||
|
|
||||||
import cloud.tianai.captcha.cache.CacheStore;
|
|
||||||
|
|
||||||
public interface CaptchaRedisCacheService extends CacheStore {
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user