From 04d149ea05b59648360fdb2fc45d9aed17d7689f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E7=88=B1=E6=9C=89=E6=83=85?= Date: Thu, 24 Feb 2022 10:18:10 +0800 Subject: [PATCH] =?UTF-8?q?U=20=E4=BC=98=E5=8C=96=20CacheSliderCaptchaTemp?= =?UTF-8?q?late=20U=20SliderCaptchaValidator=20=E5=A2=9E=E5=8A=A0=20genera?= =?UTF-8?q?teSliderCaptchaValidData=20=E6=96=B9=E6=B3=95=EF=BC=8C=20?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E7=94=A8=E6=88=B7=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E9=AA=8C=E8=AF=81=E5=8F=82=E6=95=B0=20U=20Sl?= =?UTF-8?q?iderCaptchaValidator.valid=20=E5=8F=82=E6=95=B0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=94=B1=E5=8E=9F=E6=9D=A5=E7=9A=84=E7=99=BE?= =?UTF-8?q?=E5=88=86=E6=AF=94=E6=8D=A2=E6=88=90map=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E9=80=8F=E4=BC=A0=20U=20=E5=8D=87=E7=BA=A7=E7=89=88?= =?UTF-8?q?=E6=9C=AC=20=E6=94=B9=E4=B8=BA1.2.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- readme.md | 4 +- .../slider/CacheSliderCaptchaTemplate.java | 13 +++--- .../validator/BasicCaptchaTrackValidator.java | 5 ++- .../SimpleSliderCaptchaValidator.java | 44 ++++++++++++++++++- .../validator/SliderCaptchaValidator.java | 18 ++++++-- 6 files changed, 72 insertions(+), 14 deletions(-) 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); }