diff --git a/pom.xml b/pom.xml index 696cbbf..0ba842e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 cloud.tianai.captcha tianai-captcha - 1.2.5 + 1.2.6 tianai-captcha 滑块验证码 diff --git a/readme.md b/readme.md index 54d19c5..83f1de0 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# 这是一个滑块验证码的实现 + 这是一个滑块验证码的实现 ## [在线体验](https://www.tianai.cloud) ## 验证码demo移步 [tianai-captcha-demo](https://gitee.com/tianai/tianai-captcha-demo) ## 不说废话,直接上成品 @@ -21,7 +21,7 @@ cloud.tianai.captcha tianai-captcha - 1.2.5 + 1.2.6 ``` 2. 使用 `SliderCaptchaTemplate`获取滑块验证码 diff --git a/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java b/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java index af825ab..f0ea322 100644 --- a/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java +++ b/src/main/java/cloud/tianai/captcha/template/slider/CacheSliderCaptchaTemplate.java @@ -26,14 +26,17 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate { private int waitTime = 1000; /** 调度器检查缓存的间隔时间. */ 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.generateParam = generateParam; 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.generateParam = generateParam; this.size = size; this.waitTime = waitTime; this.period = period; @@ -57,7 +60,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate { if (pos.get() >= size) { return; } - SliderCaptchaInfo slideImageInfo = target.getSlideImageInfo(); + SliderCaptchaInfo slideImageInfo = target.getSlideImageInfo(generateParam); if (slideImageInfo != null) { boolean addStatus = queue.offer(slideImageInfo); if (addStatus) { @@ -75,7 +78,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate { sleep(); } }, 0, period, TimeUnit.MILLISECONDS); - log.info("缓存滑块验证码调度器初始化完成: size:{}", size); + log.info("缓存滑块验证码调度器初始化完成: size:{}, genParam:{}", size, generateParam); } private void sleep() { @@ -90,7 +93,7 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate { public SliderCaptchaInfo getSlideImageInfo() { SliderCaptchaInfo poll = queue.poll(); if (poll == null) { - log.warn("滑块验证码缓存不足"); + log.warn("滑块验证码缓存不足, genParam:{}", generateParam); // 如果池内没数据, 则直接生成 return target.getSlideImageInfo(); } diff --git a/src/main/java/cloud/tianai/captcha/template/slider/validator/BasicCaptchaTrackValidator.java b/src/main/java/cloud/tianai/captcha/template/slider/validator/BasicCaptchaTrackValidator.java index bb79d38..f71e94e 100644 --- a/src/main/java/cloud/tianai/captcha/template/slider/validator/BasicCaptchaTrackValidator.java +++ b/src/main/java/cloud/tianai/captcha/template/slider/validator/BasicCaptchaTrackValidator.java @@ -4,6 +4,7 @@ import cloud.tianai.captcha.template.slider.util.CollectionUtils; import cloud.tianai.captcha.template.slider.util.ObjectUtils; import java.util.List; +import java.util.Map; /** * @Author: 天爱有情 @@ -20,11 +21,11 @@ public class BasicCaptchaTrackValidator extends SimpleSliderCaptchaValidator { } @Override - public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage) { + public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map sliderCaptchaValidData) { // 校验参数 checkParam(sliderCaptchaTrack); // 基础校验 - boolean superValid = super.valid(sliderCaptchaTrack, oriPercentage); + boolean superValid = super.valid(sliderCaptchaTrack, sliderCaptchaValidData); if (!superValid) { return false; } diff --git a/src/main/java/cloud/tianai/captcha/template/slider/validator/SimpleSliderCaptchaValidator.java b/src/main/java/cloud/tianai/captcha/template/slider/validator/SimpleSliderCaptchaValidator.java index 5b6806a..71653bd 100644 --- a/src/main/java/cloud/tianai/captcha/template/slider/validator/SimpleSliderCaptchaValidator.java +++ b/src/main/java/cloud/tianai/captcha/template/slider/validator/SimpleSliderCaptchaValidator.java @@ -1,15 +1,21 @@ package cloud.tianai.captcha.template.slider.validator; +import cloud.tianai.captcha.template.slider.SliderCaptchaInfo; import cloud.tianai.captcha.template.slider.util.CollectionUtils; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; import java.util.List; +import java.util.Map; + /** * @Author: 天爱有情 * @date 2022/2/17 11:01 * @Description 基本的滑块验证校验 , 值进行基本校验, 目前只校验用户是否滑动到缺口处,不校验行为轨迹 */ +@Slf4j public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator { public static float DEFAULT_TOLERANT = 0.02f; @@ -48,7 +54,19 @@ public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator { } @Override - public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage) { + public Map generateSliderCaptchaValidData(SliderCaptchaInfo sliderCaptchaInfo) { + Map map = new HashMap<>(8); + addPercentage(sliderCaptchaInfo, map); + return map; + } + + @Override + public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map sliderCaptchaValidData) { + Float oriPercentage = getPercentage(sliderCaptchaTrack, sliderCaptchaValidData); + if (oriPercentage == null) { + // 没读取到百分比 + return false; + } Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth(); if (bgImageWidth == null || bgImageWidth < 1) { // 没有背景图片宽度 @@ -66,4 +84,28 @@ public class SimpleSliderCaptchaValidator implements SliderCaptchaValidator { // 校验百分比 return checkPercentage(calcPercentage, oriPercentage); } + + protected Float getPercentage(SliderCaptchaTrack sliderCaptchaTrack, Map 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 sliderCaptchaValidData) { + float percentage = calcPercentage(sliderCaptchaInfo.getX(), sliderCaptchaInfo.getBgImageWidth()); + sliderCaptchaValidData.put("percentage", percentage); + } } diff --git a/src/main/java/cloud/tianai/captcha/template/slider/validator/SliderCaptchaValidator.java b/src/main/java/cloud/tianai/captcha/template/slider/validator/SliderCaptchaValidator.java index dea7696..d4afd78 100644 --- a/src/main/java/cloud/tianai/captcha/template/slider/validator/SliderCaptchaValidator.java +++ b/src/main/java/cloud/tianai/captcha/template/slider/validator/SliderCaptchaValidator.java @@ -1,5 +1,9 @@ package cloud.tianai.captcha.template.slider.validator; +import cloud.tianai.captcha.template.slider.SliderCaptchaInfo; + +import java.util.Map; + /** * @Author: 天爱有情 * @date 2022/2/17 10:54 @@ -35,12 +39,20 @@ public interface SliderCaptchaValidator { */ boolean checkPercentage(Float newPercentage, Float oriPercentage, float tolerant); + /** + * 用于生成验证码校验时需要的回传参数 + * + * @param sliderCaptchaInfo 生成的验证码数据 + * @return Map + */ + Map generateSliderCaptchaValidData(SliderCaptchaInfo sliderCaptchaInfo); + /** * 校验用户滑动滑块是否正确 * - * @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数 - * @param oriPercentage 正确的滑块百分比,用作基础校验 + * @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数 + * @param sliderCaptchaValidData generateSliderCaptchaValidData(生成的数据 * @return boolean */ - boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Float oriPercentage); + boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map sliderCaptchaValidData); }