mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-08-30 18:36:11 +08:00
U 优化 CacheSliderCaptchaTemplate
U SliderCaptchaValidator 增加 generateSliderCaptchaValidData 方法, 允许用户添加自定义验证参数 U SliderCaptchaValidator.valid 参数修改为由原来的百分比换成map 支持用户自定义参数的透传 U 升级版本 改为1.2.6
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>cloud.tianai.captcha</groupId>
|
<groupId>cloud.tianai.captcha</groupId>
|
||||||
<artifactId>tianai-captcha</artifactId>
|
<artifactId>tianai-captcha</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6</version>
|
||||||
|
|
||||||
<name>tianai-captcha</name>
|
<name>tianai-captcha</name>
|
||||||
<description>滑块验证码</description>
|
<description>滑块验证码</description>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# 这是一个滑块验证码的实现
|
这是一个滑块验证码的实现
|
||||||
## [在线体验](https://www.tianai.cloud)
|
## [在线体验](https://www.tianai.cloud)
|
||||||
## 验证码demo移步 [tianai-captcha-demo](https://gitee.com/tianai/tianai-captcha-demo)
|
## 验证码demo移步 [tianai-captcha-demo](https://gitee.com/tianai/tianai-captcha-demo)
|
||||||
## 不说废话,直接上成品
|
## 不说废话,直接上成品
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cloud.tianai.captcha</groupId>
|
<groupId>cloud.tianai.captcha</groupId>
|
||||||
<artifactId>tianai-captcha</artifactId>
|
<artifactId>tianai-captcha</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
2. 使用 `SliderCaptchaTemplate`获取滑块验证码
|
2. 使用 `SliderCaptchaTemplate`获取滑块验证码
|
||||||
|
|||||||
@@ -26,14 +26,17 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
|
|||||||
private int waitTime = 1000;
|
private int waitTime = 1000;
|
||||||
/** 调度器检查缓存的间隔时间. */
|
/** 调度器检查缓存的间隔时间. */
|
||||||
private int period = 100;
|
private int period = 100;
|
||||||
|
private GenerateParam generateParam;
|
||||||
|
|
||||||
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, int size) {
|
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, GenerateParam generateParam, int size) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
this.generateParam = generateParam;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, int size, int waitTime, int period) {
|
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, GenerateParam generateParam, int size, int waitTime, int period) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
this.generateParam = generateParam;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.waitTime = waitTime;
|
this.waitTime = waitTime;
|
||||||
this.period = period;
|
this.period = period;
|
||||||
@@ -57,7 +60,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
|
|||||||
if (pos.get() >= size) {
|
if (pos.get() >= size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SliderCaptchaInfo slideImageInfo = target.getSlideImageInfo();
|
SliderCaptchaInfo slideImageInfo = target.getSlideImageInfo(generateParam);
|
||||||
if (slideImageInfo != null) {
|
if (slideImageInfo != null) {
|
||||||
boolean addStatus = queue.offer(slideImageInfo);
|
boolean addStatus = queue.offer(slideImageInfo);
|
||||||
if (addStatus) {
|
if (addStatus) {
|
||||||
@@ -75,7 +78,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
|
|||||||
sleep();
|
sleep();
|
||||||
}
|
}
|
||||||
}, 0, period, TimeUnit.MILLISECONDS);
|
}, 0, period, TimeUnit.MILLISECONDS);
|
||||||
log.info("缓存滑块验证码调度器初始化完成: size:{}", size);
|
log.info("缓存滑块验证码调度器初始化完成: size:{}, genParam:{}", size, generateParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sleep() {
|
private void sleep() {
|
||||||
@@ -90,7 +93,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
|
|||||||
public SliderCaptchaInfo getSlideImageInfo() {
|
public SliderCaptchaInfo getSlideImageInfo() {
|
||||||
SliderCaptchaInfo poll = queue.poll();
|
SliderCaptchaInfo poll = queue.poll();
|
||||||
if (poll == null) {
|
if (poll == null) {
|
||||||
log.warn("滑块验证码缓存不足");
|
log.warn("滑块验证码缓存不足, genParam:{}", generateParam);
|
||||||
// 如果池内没数据, 则直接生成
|
// 如果池内没数据, 则直接生成
|
||||||
return target.getSlideImageInfo();
|
return target.getSlideImageInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -4,6 +4,7 @@ import cloud.tianai.captcha.template.slider.util.CollectionUtils;
|
|||||||
import cloud.tianai.captcha.template.slider.util.ObjectUtils;
|
import cloud.tianai.captcha.template.slider.util.ObjectUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
@@ -20,11 +21,11 @@ public class BasicCaptchaTrackValidator extends SimpleSliderCaptchaValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage) {
|
public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData) {
|
||||||
// 校验参数
|
// 校验参数
|
||||||
checkParam(sliderCaptchaTrack);
|
checkParam(sliderCaptchaTrack);
|
||||||
// 基础校验
|
// 基础校验
|
||||||
boolean superValid = super.valid(sliderCaptchaTrack, oriPercentage);
|
boolean superValid = super.valid(sliderCaptchaTrack, sliderCaptchaValidData);
|
||||||
if (!superValid) {
|
if (!superValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-1
@@ -1,15 +1,21 @@
|
|||||||
package cloud.tianai.captcha.template.slider.validator;
|
package cloud.tianai.captcha.template.slider.validator;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.template.slider.SliderCaptchaInfo;
|
||||||
import cloud.tianai.captcha.template.slider.util.CollectionUtils;
|
import cloud.tianai.captcha.template.slider.util.CollectionUtils;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
* @date 2022/2/17 11:01
|
* @date 2022/2/17 11:01
|
||||||
* @Description 基本的滑块验证校验 , 值进行基本校验, 目前只校验用户是否滑动到缺口处,不校验行为轨迹
|
* @Description 基本的滑块验证校验 , 值进行基本校验, 目前只校验用户是否滑动到缺口处,不校验行为轨迹
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator {
|
public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator {
|
||||||
|
|
||||||
public static float DEFAULT_TOLERANT = 0.02f;
|
public static float DEFAULT_TOLERANT = 0.02f;
|
||||||
@@ -48,7 +54,19 @@ public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage) {
|
public Map<String, Object> generateSliderCaptchaValidData(SliderCaptchaInfo sliderCaptchaInfo) {
|
||||||
|
Map<String, Object> map = new HashMap<>(8);
|
||||||
|
addPercentage(sliderCaptchaInfo, map);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData) {
|
||||||
|
Float oriPercentage = getPercentage(sliderCaptchaTrack, sliderCaptchaValidData);
|
||||||
|
if (oriPercentage == null) {
|
||||||
|
// 没读取到百分比
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth();
|
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth();
|
||||||
if (bgImageWidth == null || bgImageWidth < 1) {
|
if (bgImageWidth == null || bgImageWidth < 1) {
|
||||||
// 没有背景图片宽度
|
// 没有背景图片宽度
|
||||||
@@ -66,4 +84,28 @@ public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator {
|
|||||||
// 校验百分比
|
// 校验百分比
|
||||||
return checkPercentage(calcPercentage, oriPercentage);
|
return checkPercentage(calcPercentage, oriPercentage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Float getPercentage(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData) {
|
||||||
|
Object percentage = sliderCaptchaValidData.get("percentage");
|
||||||
|
if (percentage != null) {
|
||||||
|
if (percentage instanceof Number) {
|
||||||
|
return ((Number) percentage).floatValue();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (percentage instanceof String) {
|
||||||
|
return Float.parseFloat((String) percentage);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.error("从 sliderCaptchaValidData 读取到的 percentage无法转换成float类型, [{}]", percentage);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.warn("无法从 sliderCaptchaValidData 获取到 percentage");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addPercentage(SliderCaptchaInfo sliderCaptchaInfo, Map<String, Object> sliderCaptchaValidData) {
|
||||||
|
float percentage = calcPercentage(sliderCaptchaInfo.getX(), sliderCaptchaInfo.getBgImageWidth());
|
||||||
|
sliderCaptchaValidData.put("percentage", percentage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -1,5 +1,9 @@
|
|||||||
package cloud.tianai.captcha.template.slider.validator;
|
package cloud.tianai.captcha.template.slider.validator;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.template.slider.SliderCaptchaInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 天爱有情
|
* @Author: 天爱有情
|
||||||
* @date 2022/2/17 10:54
|
* @date 2022/2/17 10:54
|
||||||
@@ -35,12 +39,20 @@ public interface SliderCaptchaValidator {
|
|||||||
*/
|
*/
|
||||||
boolean checkPercentage(Float newPercentage, Float oriPercentage, float tolerant);
|
boolean checkPercentage(Float newPercentage, Float oriPercentage, float tolerant);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于生成验证码校验时需要的回传参数
|
||||||
|
*
|
||||||
|
* @param sliderCaptchaInfo 生成的验证码数据
|
||||||
|
* @return Map<String, Object>
|
||||||
|
*/
|
||||||
|
Map<String, Object> generateSliderCaptchaValidData(SliderCaptchaInfo sliderCaptchaInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验用户滑动滑块是否正确
|
* 校验用户滑动滑块是否正确
|
||||||
*
|
*
|
||||||
* @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数
|
* @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数
|
||||||
* @param oriPercentage 正确的滑块百分比,用作基础校验
|
* @param sliderCaptchaValidData generateSliderCaptchaValidData(生成的数据
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage);
|
boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user