This commit is contained in:
天爱有情
2022-05-07 09:47:09 +08:00
parent a4e0def76b
commit d802fd481a
16 changed files with 117 additions and 174 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ public class Test2 {
// 用户传来的行为轨迹和进行校验 // 用户传来的行为轨迹和进行校验
// - sliderCaptchaTrack为前端传来的滑动轨迹数据 // - sliderCaptchaTrack为前端传来的滑动轨迹数据
// - map 为生成验证码时缓存的map数据 // - map 为生成验证码时缓存的map数据
boolean check = sliderCaptchaValidator.valid(sliderCaptchaTrack, map); boolean check = sliderCaptchaValidator.valid(imageCaptchaTrack, map);
// 如果只想校验用户是否滑到指定凹槽即可,也可以使用 // 如果只想校验用户是否滑到指定凹槽即可,也可以使用
// - 参数1 用户传来的百分比数据 // - 参数1 用户传来的百分比数据
// - 参数2 生成滑块是真实的百分比数据 // - 参数2 生成滑块是真实的百分比数据
@@ -0,0 +1,27 @@
package cloud.tianai.captcha.template.slider.common.exception;
/**
* @Author: 天爱有情
* @date 2022/5/7 9:04
* @Description 图片验证码异常
*/
public class ImageCaptchaException extends RuntimeException{
public ImageCaptchaException() {
}
public ImageCaptchaException(String message) {
super(message);
}
public ImageCaptchaException(String message, Throwable cause) {
super(message, cause);
}
public ImageCaptchaException(Throwable cause) {
super(cause);
}
public ImageCaptchaException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -1,22 +0,0 @@
package cloud.tianai.captcha.template.slider.common.exception;
public class SliderCaptchaException extends RuntimeException{
public SliderCaptchaException() {
}
public SliderCaptchaException(String message) {
super(message);
}
public SliderCaptchaException(String message, Throwable cause) {
super(message, cause);
}
public SliderCaptchaException(Throwable cause) {
super(cause);
}
public SliderCaptchaException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -13,17 +13,22 @@ import java.util.concurrent.ThreadLocalRandom;
*/ */
public class FontUtils { public class FontUtils {
/**
* 获取随机文字
*
* @param random 随机数生成器
* @return String
*/
@SneakyThrows @SneakyThrows
public static String getRandomChar(Random random) { public static String getRandomChar(Random random) {
Integer hightPos, lowPos; // 定义高低位 Integer heightPos, lowPos; // 定义高低位
hightPos = (176 + Math.abs(random.nextInt(39))); heightPos = (176 + Math.abs(random.nextInt(39)));
lowPos = (161 + Math.abs(random.nextInt(93))); lowPos = (161 + Math.abs(random.nextInt(93)));
byte[] bytes = new byte[2]; byte[] bytes = new byte[2];
bytes[0] = hightPos.byteValue(); bytes[0] = heightPos.byteValue();
bytes[1] = lowPos.byteValue(); bytes[1] = lowPos.byteValue();
return new String(bytes, "GBK"); return new String(bytes, "GBK");
} }
} }
@@ -391,7 +391,8 @@ public class CaptchaImageUtils {
y1 = y2; y1 = y2;
y2 = ty; y2 = ty;
} }
if (random.nextInt(2) == 0) { // 二阶贝塞尔曲线 // 二阶贝塞尔曲线
if (random.nextInt(2) == 0) {
QuadCurve2D shape = new QuadCurve2D.Double(); QuadCurve2D shape = new QuadCurve2D.Double();
shape.setCurve(x1, y1, ctrlx, ctrly, x2, y2); shape.setCurve(x1, y1, ctrlx, ctrly, x2, y2);
g.draw(shape); g.draw(shape);
@@ -93,8 +93,6 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
} }
} }
} }
// return null;
} }
@@ -93,7 +93,6 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
// 随机x 转换为角度 // 随机x 转换为角度
int randomX = ThreadLocalRandom.current().nextInt(fixedTemplate.getWidth() + 10, targetBackground.getWidth() - 10); int randomX = ThreadLocalRandom.current().nextInt(fixedTemplate.getWidth() + 10, targetBackground.getWidth() - 10);
double degree = 360d - randomX / ((targetBackground.getWidth()) / 360d); double degree = 360d - randomX / ((targetBackground.getWidth()) / 360d);
// int degree = ThreadLocalRandom.current().nextInt(10, 350);
centerOverlayAndRotateImage(matrixTemplate, cutImage, degree); centerOverlayAndRotateImage(matrixTemplate, cutImage, degree);
return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param); return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param);
} finally { } finally {
@@ -19,5 +19,11 @@ public abstract class AbstractResourceProvider implements ResourceProvider {
return resourceInputStream; return resourceInputStream;
} }
/**
* 通过 Resource 获取 InputStream
*
* @param data data
* @return InputStream
*/
public abstract InputStream doGetResourceInputStream(Resource data); public abstract InputStream doGetResourceInputStream(Resource data);
} }
@@ -16,6 +16,7 @@ public interface ImageCaptchaResourceManager {
/** /**
* 随机获取某个模板 * 随机获取某个模板
* *
* @param type 验证码类型
* @return Map<String, Resource> * @return Map<String, Resource>
*/ */
Map<String, Resource> randomGetTemplate(String type); Map<String, Resource> randomGetTemplate(String type);
@@ -23,6 +24,7 @@ public interface ImageCaptchaResourceManager {
/** /**
* 随机获取某个资源对象 * 随机获取某个资源对象
* *
* @param type 验证码类型
* @return Resource * @return Resource
*/ */
Resource randomGetResource(String type); Resource randomGetResource(String type);
@@ -5,11 +5,17 @@ import cloud.tianai.captcha.template.slider.resource.common.model.dto.Resource;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
* @Author: 天爱有情
* @date 2022/5/7 9:04
* @Description 资源存储
*/
public interface ResourceStore { public interface ResourceStore {
/** /**
* 添加资源 * 添加资源
* *
* @param type 验证码类型
* @param resource 资源 * @param resource 资源
*/ */
void addResource(String type, Resource resource); void addResource(String type, Resource resource);
@@ -67,7 +73,8 @@ public interface ResourceStore {
/** /**
* 添加模板 * 添加模板
* *
* @param template template * @param type 验证码类型
* @param template 模板
*/ */
void addTemplate(String type, Map<String, Resource> template); void addTemplate(String type, Map<String, Resource> template);
@@ -86,6 +93,7 @@ public interface ResourceStore {
/** /**
* 获取所有模板通过type * 获取所有模板通过type
* *
* @param type 验证码类型
* @return List<Map < String, Resource>> * @return List<Map < String, Resource>>
*/ */
List<Map<String, Resource>> listTemplatesByType(String type); List<Map<String, Resource>> listTemplatesByType(String type);
@@ -1,79 +0,0 @@
package cloud.tianai.captcha.template.slider.resource;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* @Author: 天爱有情
* @date 2020/10/19 18:38
* @Description 滑块验证码资源
*/
public interface SliderCaptchaResource {
/**
* 添加资源
*
* @param url url
*/
void addResource(URL url);
/**
* 设置资源
*
* @param resources resources
*/
void setResource(List<URL> resources);
/**
* 删除资源
*
* @param resource resource
*/
void deleteResource(URL resource);
/**
* 读取所有资源
*
* @return List<URL>
*/
List<URL> listResources();
/**
* 清除所有资源
*/
void clearResources();
/**
* 添加模板
*
* @param template template
*/
void addTemplate(Map<String, URL> template);
/**
* 设置模板
*
* @param imageTemplates imageTemplates
*/
void setTemplates(List<Map<String, URL>> imageTemplates);
/**
* 删除模板
*
* @param template template
*/
void deleteTemplate(Map<String, URL> template);
/**
* 查询所有模板
*
* @return List<Map < String, URL>>
*/
List<Map<String, URL>> listTemplates();
/**
* 清除所有模板
*/
void clearTemplates();
}
@@ -21,9 +21,10 @@ import java.util.Map;
*/ */
public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceManager { public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceManager {
/** 资源存储. */
private ResourceStore resourceStore; private ResourceStore resourceStore;
/** 资源转换 转换为stream流. */
private List<ResourceProvider> resourceProviderList = new ArrayList<>(8); private final List<ResourceProvider> resourceProviderList = new ArrayList<>(8);
public DefaultImageCaptchaResourceManager() { public DefaultImageCaptchaResourceManager() {
@@ -1,7 +1,7 @@
package cloud.tianai.captcha.template.slider.validator; package cloud.tianai.captcha.template.slider.validator;
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo; import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.template.slider.validator.common.model.dto.SliderCaptchaTrack; import cloud.tianai.captcha.template.slider.validator.common.model.dto.ImageCaptchaTrack;
import java.util.Map; import java.util.Map;
@@ -51,9 +51,9 @@ public interface ImageCaptchaValidator {
/** /**
* 校验用户滑动滑块是否正确 * 校验用户滑动滑块是否正确
* *
* @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数 * @param imageCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数
* @param sliderCaptchaValidData generateSliderCaptchaValidData(生成的数据 * @param sliderCaptchaValidData generateSliderCaptchaValidData(生成的数据
* @return boolean * @return boolean
*/ */
boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData); boolean valid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData);
} }
@@ -11,10 +11,10 @@ import java.util.List;
/** /**
* @Author: 天爱有情 * @Author: 天爱有情
* @date 2022/2/17 9:23 * @date 2022/2/17 9:23
* @Description 滑块验证码滑动轨迹 * @Description 图片验证码滑动轨迹
*/ */
@Data @Data
public class SliderCaptchaTrack { public class ImageCaptchaTrack {
/** 背景图片宽度. */ /** 背景图片宽度. */
private Integer bgImageWidth; private Integer bgImageWidth;
@@ -32,7 +32,6 @@ public class SliderCaptchaTrack {
private List<Track> trackList; private List<Track> trackList;
@Data @Data
//#I4WQ4F
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class Track { public static class Track {
@@ -3,7 +3,7 @@ package cloud.tianai.captcha.template.slider.validator.impl;
import cloud.tianai.captcha.template.slider.common.util.CaptchaUtils; import cloud.tianai.captcha.template.slider.common.util.CaptchaUtils;
import cloud.tianai.captcha.template.slider.common.util.CollectionUtils; import cloud.tianai.captcha.template.slider.common.util.CollectionUtils;
import cloud.tianai.captcha.template.slider.common.util.ObjectUtils; import cloud.tianai.captcha.template.slider.common.util.ObjectUtils;
import cloud.tianai.captcha.template.slider.validator.common.model.dto.SliderCaptchaTrack; import cloud.tianai.captcha.template.slider.validator.common.model.dto.ImageCaptchaTrack;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -23,23 +23,23 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
} }
@Override @Override
public boolean beforeValid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) { public boolean beforeValid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) {
// 校验参数 // 校验参数
checkParam(sliderCaptchaTrack); checkParam(imageCaptchaTrack);
return true; return true;
} }
@Override @Override
public boolean afterValid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) { public boolean afterValid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) {
if (!CaptchaUtils.isSliderCaptcha(type)){ if (!CaptchaUtils.isSliderCaptcha(type)){
// 不是滑动验证码的话暂时跳过,点选验证码行为轨迹还没做 // 不是滑动验证码的话暂时跳过,点选验证码行为轨迹还没做
return true; return true;
} }
// 进行行为轨迹检测 // 进行行为轨迹检测
long startSlidingTime = sliderCaptchaTrack.getStartSlidingTime().getTime(); long startSlidingTime = imageCaptchaTrack.getStartSlidingTime().getTime();
long endSlidingTime = sliderCaptchaTrack.getEntSlidingTime().getTime(); long endSlidingTime = imageCaptchaTrack.getEntSlidingTime().getTime();
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth(); Integer bgImageWidth = imageCaptchaTrack.getBgImageWidth();
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList(); List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
// 这里只进行基本检测, 用一些简单算法进行校验,如有需要可扩展 // 这里只进行基本检测, 用一些简单算法进行校验,如有需要可扩展
// 检测1: 滑动时间如果小于300毫秒 返回false // 检测1: 滑动时间如果小于300毫秒 返回false
// 检测2: 轨迹数据要是少于背10,或者大于背景宽度的五倍 返回false // 检测2: 轨迹数据要是少于背10,或者大于背景宽度的五倍 返回false
@@ -58,14 +58,14 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
return false; return false;
} }
// 检测3 // 检测3
SliderCaptchaTrack.Track firstTrack = trackList.get(0); ImageCaptchaTrack.Track firstTrack = trackList.get(0);
if (firstTrack.getX() > 10 || firstTrack.getX() < -10 || firstTrack.getY() > 10 || firstTrack.getY() < -10) { if (firstTrack.getX() > 10 || firstTrack.getX() < -10 || firstTrack.getY() > 10 || firstTrack.getY() < -10) {
return false; return false;
} }
int check4 = 0; int check4 = 0;
int check7 = 0; int check7 = 0;
for (int i = 1; i < trackList.size(); i++) { for (int i = 1; i < trackList.size(); i++) {
SliderCaptchaTrack.Track track = trackList.get(i); ImageCaptchaTrack.Track track = trackList.get(i);
int x = track.getX(); int x = track.getX();
int y = track.getY(); int y = track.getY();
// check4 // check4
@@ -77,7 +77,7 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
check7++; check7++;
} }
// check5 // check5
SliderCaptchaTrack.Track preTrack = trackList.get(i - 1); ImageCaptchaTrack.Track preTrack = trackList.get(i - 1);
if ((track.getX() - preTrack.getX()) > 50 || (track.getY() - preTrack.getY()) > 50) { if ((track.getX() - preTrack.getX()) > 50 || (track.getY() - preTrack.getY()) > 50) {
return false; return false;
} }
@@ -88,39 +88,33 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
// check6 // check6
int splitPos = (int) (trackList.size() * 0.7); int splitPos = (int) (trackList.size() * 0.7);
SliderCaptchaTrack.Track splitPostTrack = trackList.get(splitPos - 1); ImageCaptchaTrack.Track splitPostTrack = trackList.get(splitPos - 1);
int posTime = splitPostTrack.getT(); int posTime = splitPostTrack.getT();
float startAvgPosTime = posTime / (float) splitPos; float startAvgPosTime = posTime / (float) splitPos;
SliderCaptchaTrack.Track lastTrack = trackList.get(trackList.size() - 1); ImageCaptchaTrack.Track lastTrack = trackList.get(trackList.size() - 1);
float endAvgPosTime = lastTrack.getT() / (float) (trackList.size() - splitPos); float endAvgPosTime = lastTrack.getT() / (float) (trackList.size() - splitPos);
return endAvgPosTime > startAvgPosTime; return endAvgPosTime > startAvgPosTime;
} }
public void checkParam(SliderCaptchaTrack sliderCaptchaTrack) { public void checkParam(ImageCaptchaTrack imageCaptchaTrack) {
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getBgImageWidth())) { if (ObjectUtils.isEmpty(imageCaptchaTrack.getBgImageWidth())) {
throw new IllegalArgumentException("bgImageWidth must not be null"); throw new IllegalArgumentException("bgImageWidth must not be null");
} }
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getBgImageHeight())) { if (ObjectUtils.isEmpty(imageCaptchaTrack.getBgImageHeight())) {
throw new IllegalArgumentException("bgImageHeight must not be null"); throw new IllegalArgumentException("bgImageHeight must not be null");
} }
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getSliderImageWidth())) { if (ObjectUtils.isEmpty(imageCaptchaTrack.getStartSlidingTime())) {
throw new IllegalArgumentException("sliderImageWidth must not be null");
}
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getSliderImageHeight())) {
throw new IllegalArgumentException("sliderImageHeight must not be null");
}
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getStartSlidingTime())) {
throw new IllegalArgumentException("startSlidingTime must not be null"); throw new IllegalArgumentException("startSlidingTime must not be null");
} }
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getEntSlidingTime())) { if (ObjectUtils.isEmpty(imageCaptchaTrack.getEntSlidingTime())) {
throw new IllegalArgumentException("entSlidingTime must not be null"); throw new IllegalArgumentException("entSlidingTime must not be null");
} }
if (CollectionUtils.isEmpty(sliderCaptchaTrack.getTrackList())) { if (CollectionUtils.isEmpty(imageCaptchaTrack.getTrackList())) {
throw new IllegalArgumentException("trackList must not be null"); throw new IllegalArgumentException("trackList must not be null");
} }
for (SliderCaptchaTrack.Track track : sliderCaptchaTrack.getTrackList()) { for (ImageCaptchaTrack.Track track : imageCaptchaTrack.getTrackList()) {
Integer x = track.getX(); Integer x = track.getX();
Integer y = track.getY(); Integer y = track.getY();
Integer t = track.getT(); Integer t = track.getT();
@@ -8,7 +8,7 @@ import cloud.tianai.captcha.template.slider.generator.common.model.dto.ClickImag
import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo; import cloud.tianai.captcha.template.slider.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.template.slider.validator.ImageCaptchaValidator; import cloud.tianai.captcha.template.slider.validator.ImageCaptchaValidator;
import cloud.tianai.captcha.template.slider.validator.common.constant.TrackTypeConstant; import cloud.tianai.captcha.template.slider.validator.common.constant.TrackTypeConstant;
import cloud.tianai.captcha.template.slider.validator.common.model.dto.SliderCaptchaTrack; import cloud.tianai.captcha.template.slider.validator.common.model.dto.ImageCaptchaTrack;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -26,9 +26,13 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
public class SimpleImageCaptchaValidator implements ImageCaptchaValidator { public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
/** 默认的容错值. */
public static float DEFAULT_TOLERANT = 0.02f; public static float DEFAULT_TOLERANT = 0.02f;
/** 验证数据 key. */
public static final String PERCENTAGE_KEY = "percentage"; public static final String PERCENTAGE_KEY = "percentage";
/** 容错值key. */
public static final String TOLERANT_KEY = "tolerant"; public static final String TOLERANT_KEY = "tolerant";
/** 类型 key, 标识是哪张类型的验证码. */
public static final String TYPE_KEY = "type"; public static final String TYPE_KEY = "type";
/** 容错值. */ /** 容错值. */
@@ -68,7 +72,7 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
@Override @Override
public Map<String, Object> generateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo) { public Map<String, Object> generateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo) {
Map<String, Object> map = new HashMap<>(8); Map<String, Object> map = new HashMap<>(8);
if(beforeGenerateImageCaptchaValidData(imageCaptchaInfo, map)) { if (beforeGenerateImageCaptchaValidData(imageCaptchaInfo, map)) {
doGenerateImageCaptchaValidData(map, imageCaptchaInfo); doGenerateImageCaptchaValidData(map, imageCaptchaInfo);
} }
afterGenerateImageCaptchaValidData(imageCaptchaInfo, map); afterGenerateImageCaptchaValidData(imageCaptchaInfo, map);
@@ -136,30 +140,30 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
} }
@Override @Override
public boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData) { public boolean valid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData) {
// 读容错值 // 读容错值
Float tolerant = getFloatParam(TOLERANT_KEY, sliderCaptchaValidData, defaultTolerant); Float tolerant = getFloatParam(TOLERANT_KEY, sliderCaptchaValidData, defaultTolerant);
// 读验证码类型 // 读验证码类型
String type = getStringParam(TYPE_KEY, sliderCaptchaValidData, CaptchaTypeConstant.SLIDER); String type = getStringParam(TYPE_KEY, sliderCaptchaValidData, CaptchaTypeConstant.SLIDER);
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth(); Integer bgImageWidth = imageCaptchaTrack.getBgImageWidth();
if (bgImageWidth == null || bgImageWidth < 1) { if (bgImageWidth == null || bgImageWidth < 1) {
// 没有背景图片宽度 // 没有背景图片宽度
return false; return false;
} }
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList(); List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
if (CollectionUtils.isEmpty(trackList)) { if (CollectionUtils.isEmpty(trackList)) {
// 没有滑动轨迹 // 没有滑动轨迹
return false; return false;
} }
// 验证前 // 验证前
if (!beforeValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type)) { if (!beforeValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type)) {
return false; return false;
} }
// 验证 // 验证
boolean valid = doValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type); boolean valid = doValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
if (valid) { if (valid) {
// 验证后 // 验证后
valid = afterValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type); valid = afterValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
} }
return valid; return valid;
} }
@@ -167,39 +171,39 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
/** /**
* 验证前 * 验证前
* *
* @param sliderCaptchaTrack sliderCaptchaTrack * @param imageCaptchaTrack sliderCaptchaTrack
* @param sliderCaptchaValidData sliderCaptchaValidData * @param sliderCaptchaValidData sliderCaptchaValidData
* @param tolerant tolerant * @param tolerant tolerant
* @param type type * @param type type
* @return boolean * @return boolean
*/ */
public boolean beforeValid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) { public boolean beforeValid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) {
return true; return true;
} }
/** /**
* 验证后 * 验证后
* *
* @param sliderCaptchaTrack sliderCaptchaTrack * @param imageCaptchaTrack sliderCaptchaTrack
* @param sliderCaptchaValidData sliderCaptchaValidData * @param sliderCaptchaValidData sliderCaptchaValidData
* @param tolerant tolerant * @param tolerant tolerant
* @param type type * @param type type
* @return boolean * @return boolean
*/ */
public boolean afterValid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) { public boolean afterValid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData, Float tolerant, String type) {
return true; return true;
} }
public boolean doValid(SliderCaptchaTrack sliderCaptchaTrack, public boolean doValid(ImageCaptchaTrack imageCaptchaTrack,
Map<String, Object> sliderCaptchaValidData, Map<String, Object> sliderCaptchaValidData,
Float tolerant, Float tolerant,
String type) { String type) {
if (CaptchaUtils.isSliderCaptcha(type)) { if (CaptchaUtils.isSliderCaptcha(type)) {
// 滑动类型验证码 // 滑动类型验证码
return doValidSliderCaptcha(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type); return doValidSliderCaptcha(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
} else if (CaptchaUtils.isClickCaptcha(type)) { } else if (CaptchaUtils.isClickCaptcha(type)) {
// 点选类型验证码 // 点选类型验证码
return doValidClickCaptcha(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type); return doValidClickCaptcha(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
} }
// 不支持的类型 // 不支持的类型
log.warn("校验验证码警告, 不支持的验证码类型:{}, 请手动扩展 cloud.tianai.captcha.template.slider.validator.impl.SimpleImageCaptchaValidator.doValid 进行校验扩展", type); log.warn("校验验证码警告, 不支持的验证码类型:{}, 请手动扩展 cloud.tianai.captcha.template.slider.validator.impl.SimpleImageCaptchaValidator.doValid 进行校验扩展", type);
@@ -209,13 +213,13 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
/** /**
* 校验点选验证码 * 校验点选验证码
* *
* @param sliderCaptchaTrack sliderCaptchaTrack * @param imageCaptchaTrack sliderCaptchaTrack
* @param sliderCaptchaValidData sliderCaptchaValidData * @param sliderCaptchaValidData sliderCaptchaValidData
* @param tolerant tolerant * @param tolerant tolerant
* @param type type * @param type type
* @return boolean * @return boolean
*/ */
public boolean doValidClickCaptcha(SliderCaptchaTrack sliderCaptchaTrack, public boolean doValidClickCaptcha(ImageCaptchaTrack imageCaptchaTrack,
Map<String, Object> sliderCaptchaValidData, Map<String, Object> sliderCaptchaValidData,
Float tolerant, Float tolerant,
String type) { String type) {
@@ -224,12 +228,12 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
return false; return false;
} }
String[] splitArr = validStr.split(";"); String[] splitArr = validStr.split(";");
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList(); List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
if (trackList.size() < splitArr.length) { if (trackList.size() < splitArr.length) {
return false; return false;
} }
// 取出点击事件的轨迹数据 // 取出点击事件的轨迹数据
List<SliderCaptchaTrack.Track> clickTrackList = trackList List<ImageCaptchaTrack.Track> clickTrackList = trackList
.stream() .stream()
.filter(t -> TrackTypeConstant.CLICK.equalsIgnoreCase(t.getType())) .filter(t -> TrackTypeConstant.CLICK.equalsIgnoreCase(t.getType()))
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -237,14 +241,14 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
return false; return false;
} }
for (int i = 0; i < splitArr.length; i++) { for (int i = 0; i < splitArr.length; i++) {
SliderCaptchaTrack.Track track = clickTrackList.get(i); ImageCaptchaTrack.Track track = clickTrackList.get(i);
String posStr = splitArr[i]; String posStr = splitArr[i];
String[] posArr = posStr.split(","); String[] posArr = posStr.split(",");
float xPercentage = Float.parseFloat(posArr[0]); float xPercentage = Float.parseFloat(posArr[0]);
float yPercentage = Float.parseFloat(posArr[1]); float yPercentage = Float.parseFloat(posArr[1]);
float calcXPercentage = calcPercentage(track.getX(), sliderCaptchaTrack.getBgImageWidth()); float calcXPercentage = calcPercentage(track.getX(), imageCaptchaTrack.getBgImageWidth());
float calcYPercentage = calcPercentage(track.getY(), sliderCaptchaTrack.getBgImageHeight()); float calcYPercentage = calcPercentage(track.getY(), imageCaptchaTrack.getBgImageHeight());
if (!checkPercentage(calcXPercentage, xPercentage, tolerant) if (!checkPercentage(calcXPercentage, xPercentage, tolerant)
|| !checkPercentage(calcYPercentage, yPercentage, tolerant)) { || !checkPercentage(calcYPercentage, yPercentage, tolerant)) {
@@ -257,13 +261,13 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
/** /**
* 校验滑动验证码 * 校验滑动验证码
* *
* @param sliderCaptchaTrack sliderCaptchaTrack * @param imageCaptchaTrack sliderCaptchaTrack
* @param sliderCaptchaValidData sliderCaptchaValidData * @param sliderCaptchaValidData sliderCaptchaValidData
* @param tolerant tolerant * @param tolerant tolerant
* @param type type * @param type type
* @return boolean * @return boolean
*/ */
public boolean doValidSliderCaptcha(SliderCaptchaTrack sliderCaptchaTrack, public boolean doValidSliderCaptcha(ImageCaptchaTrack imageCaptchaTrack,
Map<String, Object> sliderCaptchaValidData, Map<String, Object> sliderCaptchaValidData,
Float tolerant, Float tolerant,
String type) { String type) {
@@ -272,11 +276,11 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
// 没读取到百分比 // 没读取到百分比
return false; return false;
} }
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList(); List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
// 取最后一个滑动轨迹 // 取最后一个滑动轨迹
SliderCaptchaTrack.Track lastTrack = trackList.get(trackList.size() - 1); ImageCaptchaTrack.Track lastTrack = trackList.get(trackList.size() - 1);
// 计算百分比 // 计算百分比
float calcPercentage = calcPercentage(lastTrack.getX(), sliderCaptchaTrack.getBgImageWidth()); float calcPercentage = calcPercentage(lastTrack.getX(), imageCaptchaTrack.getBgImageWidth());
// 校验百分比 // 校验百分比
return checkPercentage(calcPercentage, oriPercentage, tolerant); return checkPercentage(calcPercentage, oriPercentage, tolerant);
} }