mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 06:04:34 +08:00
优化
This commit is contained in:
@@ -69,7 +69,7 @@ public class Test2 {
|
||||
// 用户传来的行为轨迹和进行校验
|
||||
// - sliderCaptchaTrack为前端传来的滑动轨迹数据
|
||||
// - map 为生成验证码时缓存的map数据
|
||||
boolean check = sliderCaptchaValidator.valid(sliderCaptchaTrack, map);
|
||||
boolean check = sliderCaptchaValidator.valid(imageCaptchaTrack, map);
|
||||
// 如果只想校验用户是否滑到指定凹槽即可,也可以使用
|
||||
// - 参数1 用户传来的百分比数据
|
||||
// - 参数2 生成滑块是真实的百分比数据
|
||||
|
||||
+27
@@ -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);
|
||||
}
|
||||
}
|
||||
-22
@@ -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 {
|
||||
|
||||
/**
|
||||
* 获取随机文字
|
||||
*
|
||||
* @param random 随机数生成器
|
||||
* @return String
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String getRandomChar(Random random) {
|
||||
Integer hightPos, lowPos; // 定义高低位
|
||||
hightPos = (176 + Math.abs(random.nextInt(39)));
|
||||
Integer heightPos, lowPos; // 定义高低位
|
||||
heightPos = (176 + Math.abs(random.nextInt(39)));
|
||||
lowPos = (161 + Math.abs(random.nextInt(93)));
|
||||
byte[] bytes = new byte[2];
|
||||
bytes[0] = hightPos.byteValue();
|
||||
bytes[0] = heightPos.byteValue();
|
||||
bytes[1] = lowPos.byteValue();
|
||||
return new String(bytes, "GBK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -391,7 +391,8 @@ public class CaptchaImageUtils {
|
||||
y1 = y2;
|
||||
y2 = ty;
|
||||
}
|
||||
if (random.nextInt(2) == 0) { // 二阶贝塞尔曲线
|
||||
// 二阶贝塞尔曲线
|
||||
if (random.nextInt(2) == 0) {
|
||||
QuadCurve2D shape = new QuadCurve2D.Double();
|
||||
shape.setCurve(x1, y1, ctrlx, ctrly, x2, y2);
|
||||
g.draw(shape);
|
||||
|
||||
-2
@@ -93,8 +93,6 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
-1
@@ -93,7 +93,6 @@ public class StandardRotateImageCaptchaGenerator extends AbstractImageCaptchaGen
|
||||
// 随机x, 转换为角度
|
||||
int randomX = ThreadLocalRandom.current().nextInt(fixedTemplate.getWidth() + 10, targetBackground.getWidth() - 10);
|
||||
double degree = 360d - randomX / ((targetBackground.getWidth()) / 360d);
|
||||
// int degree = ThreadLocalRandom.current().nextInt(10, 350);
|
||||
centerOverlayAndRotateImage(matrixTemplate, cutImage, degree);
|
||||
return wrapRotateCaptchaInfo(degree, randomX, targetBackground, matrixTemplate, param);
|
||||
} finally {
|
||||
|
||||
+6
@@ -19,5 +19,11 @@ public abstract class AbstractResourceProvider implements ResourceProvider {
|
||||
return resourceInputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 Resource 获取 InputStream
|
||||
*
|
||||
* @param data data
|
||||
* @return InputStream
|
||||
*/
|
||||
public abstract InputStream doGetResourceInputStream(Resource data);
|
||||
}
|
||||
|
||||
+2
@@ -16,6 +16,7 @@ public interface ImageCaptchaResourceManager {
|
||||
/**
|
||||
* 随机获取某个模板
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @return Map<String, Resource>
|
||||
*/
|
||||
Map<String, Resource> randomGetTemplate(String type);
|
||||
@@ -23,6 +24,7 @@ public interface ImageCaptchaResourceManager {
|
||||
/**
|
||||
* 随机获取某个资源对象
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @return Resource
|
||||
*/
|
||||
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.Map;
|
||||
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/5/7 9:04
|
||||
* @Description 资源存储
|
||||
*/
|
||||
public interface ResourceStore {
|
||||
|
||||
/**
|
||||
* 添加资源
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @param 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);
|
||||
|
||||
@@ -86,6 +93,7 @@ public interface ResourceStore {
|
||||
/**
|
||||
* 获取所有模板通过type
|
||||
*
|
||||
* @param type 验证码类型
|
||||
* @return List<Map < String, Resource>>
|
||||
*/
|
||||
List<Map<String, Resource>> listTemplatesByType(String type);
|
||||
|
||||
-79
@@ -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();
|
||||
}
|
||||
+3
-2
@@ -21,9 +21,10 @@ import java.util.Map;
|
||||
*/
|
||||
public class DefaultImageCaptchaResourceManager implements ImageCaptchaResourceManager {
|
||||
|
||||
/** 资源存储. */
|
||||
private ResourceStore resourceStore;
|
||||
|
||||
private List<ResourceProvider> resourceProviderList = new ArrayList<>(8);
|
||||
/** 资源转换 转换为stream流. */
|
||||
private final List<ResourceProvider> resourceProviderList = new ArrayList<>(8);
|
||||
|
||||
|
||||
public DefaultImageCaptchaResourceManager() {
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package cloud.tianai.captcha.template.slider.validator;
|
||||
|
||||
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;
|
||||
|
||||
@@ -51,9 +51,9 @@ public interface ImageCaptchaValidator {
|
||||
/**
|
||||
* 校验用户滑动滑块是否正确
|
||||
*
|
||||
* @param sliderCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数
|
||||
* @param imageCaptchaTrack 包含了滑动轨迹,展示的图片宽高,滑动时间等参数
|
||||
* @param sliderCaptchaValidData generateSliderCaptchaValidData(生成的数据
|
||||
* @return boolean
|
||||
*/
|
||||
boolean valid(SliderCaptchaTrack sliderCaptchaTrack, Map<String, Object> sliderCaptchaValidData);
|
||||
boolean valid(ImageCaptchaTrack imageCaptchaTrack, Map<String, Object> sliderCaptchaValidData);
|
||||
}
|
||||
|
||||
+2
-3
@@ -11,10 +11,10 @@ import java.util.List;
|
||||
/**
|
||||
* @Author: 天爱有情
|
||||
* @date 2022/2/17 9:23
|
||||
* @Description 滑块验证码滑动轨迹
|
||||
* @Description 图片验证码滑动轨迹
|
||||
*/
|
||||
@Data
|
||||
public class SliderCaptchaTrack {
|
||||
public class ImageCaptchaTrack {
|
||||
|
||||
/** 背景图片宽度. */
|
||||
private Integer bgImageWidth;
|
||||
@@ -32,7 +32,6 @@ public class SliderCaptchaTrack {
|
||||
private List<Track> trackList;
|
||||
|
||||
@Data
|
||||
//#I4WQ4F
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Track {
|
||||
+20
-26
@@ -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.CollectionUtils;
|
||||
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.Map;
|
||||
@@ -23,23 +23,23 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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)){
|
||||
// 不是滑动验证码的话暂时跳过,点选验证码行为轨迹还没做
|
||||
return true;
|
||||
}
|
||||
// 进行行为轨迹检测
|
||||
long startSlidingTime = sliderCaptchaTrack.getStartSlidingTime().getTime();
|
||||
long endSlidingTime = sliderCaptchaTrack.getEntSlidingTime().getTime();
|
||||
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth();
|
||||
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList();
|
||||
long startSlidingTime = imageCaptchaTrack.getStartSlidingTime().getTime();
|
||||
long endSlidingTime = imageCaptchaTrack.getEntSlidingTime().getTime();
|
||||
Integer bgImageWidth = imageCaptchaTrack.getBgImageWidth();
|
||||
List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
|
||||
// 这里只进行基本检测, 用一些简单算法进行校验,如有需要可扩展
|
||||
// 检测1: 滑动时间如果小于300毫秒 返回false
|
||||
// 检测2: 轨迹数据要是少于背10,或者大于背景宽度的五倍 返回false
|
||||
@@ -58,14 +58,14 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
|
||||
return false;
|
||||
}
|
||||
// 检测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) {
|
||||
return false;
|
||||
}
|
||||
int check4 = 0;
|
||||
int check7 = 0;
|
||||
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 y = track.getY();
|
||||
// check4
|
||||
@@ -77,7 +77,7 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
|
||||
check7++;
|
||||
}
|
||||
// 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) {
|
||||
return false;
|
||||
}
|
||||
@@ -88,39 +88,33 @@ public class BasicCaptchaTrackValidator extends SimpleImageCaptchaValidator {
|
||||
|
||||
// check6
|
||||
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();
|
||||
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);
|
||||
|
||||
return endAvgPosTime > startAvgPosTime;
|
||||
}
|
||||
|
||||
public void checkParam(SliderCaptchaTrack sliderCaptchaTrack) {
|
||||
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getBgImageWidth())) {
|
||||
public void checkParam(ImageCaptchaTrack imageCaptchaTrack) {
|
||||
if (ObjectUtils.isEmpty(imageCaptchaTrack.getBgImageWidth())) {
|
||||
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");
|
||||
}
|
||||
if (ObjectUtils.isEmpty(sliderCaptchaTrack.getSliderImageWidth())) {
|
||||
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())) {
|
||||
if (ObjectUtils.isEmpty(imageCaptchaTrack.getStartSlidingTime())) {
|
||||
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");
|
||||
}
|
||||
if (CollectionUtils.isEmpty(sliderCaptchaTrack.getTrackList())) {
|
||||
if (CollectionUtils.isEmpty(imageCaptchaTrack.getTrackList())) {
|
||||
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 y = track.getY();
|
||||
Integer t = track.getT();
|
||||
|
||||
+33
-29
@@ -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.validator.ImageCaptchaValidator;
|
||||
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.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -26,9 +26,13 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
|
||||
/** 默认的容错值. */
|
||||
public static float DEFAULT_TOLERANT = 0.02f;
|
||||
/** 验证数据 key. */
|
||||
public static final String PERCENTAGE_KEY = "percentage";
|
||||
/** 容错值key. */
|
||||
public static final String TOLERANT_KEY = "tolerant";
|
||||
/** 类型 key, 标识是哪张类型的验证码. */
|
||||
public static final String TYPE_KEY = "type";
|
||||
|
||||
/** 容错值. */
|
||||
@@ -68,14 +72,14 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
@Override
|
||||
public Map<String, Object> generateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo) {
|
||||
Map<String, Object> map = new HashMap<>(8);
|
||||
if(beforeGenerateImageCaptchaValidData(imageCaptchaInfo, map)) {
|
||||
if (beforeGenerateImageCaptchaValidData(imageCaptchaInfo, map)) {
|
||||
doGenerateImageCaptchaValidData(map, imageCaptchaInfo);
|
||||
}
|
||||
afterGenerateImageCaptchaValidData(imageCaptchaInfo, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
public boolean beforeGenerateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> map) {
|
||||
public boolean beforeGenerateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> map) {
|
||||
// 容错值
|
||||
Float tolerant = imageCaptchaInfo.getTolerant();
|
||||
if (tolerant != null && tolerant > 0) {
|
||||
@@ -90,7 +94,7 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void afterGenerateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> map) {
|
||||
public void afterGenerateImageCaptchaValidData(ImageCaptchaInfo imageCaptchaInfo, Map<String, Object> map) {
|
||||
|
||||
}
|
||||
|
||||
@@ -136,30 +140,30 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
}
|
||||
|
||||
@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);
|
||||
// 读验证码类型
|
||||
String type = getStringParam(TYPE_KEY, sliderCaptchaValidData, CaptchaTypeConstant.SLIDER);
|
||||
Integer bgImageWidth = sliderCaptchaTrack.getBgImageWidth();
|
||||
Integer bgImageWidth = imageCaptchaTrack.getBgImageWidth();
|
||||
if (bgImageWidth == null || bgImageWidth < 1) {
|
||||
// 没有背景图片宽度
|
||||
return false;
|
||||
}
|
||||
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList();
|
||||
List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
|
||||
if (CollectionUtils.isEmpty(trackList)) {
|
||||
// 没有滑动轨迹
|
||||
return false;
|
||||
}
|
||||
// 验证前
|
||||
if (!beforeValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type)) {
|
||||
if (!beforeValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type)) {
|
||||
return false;
|
||||
}
|
||||
// 验证
|
||||
boolean valid = doValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type);
|
||||
boolean valid = doValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
|
||||
if (valid) {
|
||||
// 验证后
|
||||
valid = afterValid(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type);
|
||||
valid = afterValid(imageCaptchaTrack, sliderCaptchaValidData, tolerant, type);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@@ -167,39 +171,39 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
/**
|
||||
* 验证前
|
||||
*
|
||||
* @param sliderCaptchaTrack sliderCaptchaTrack
|
||||
* @param imageCaptchaTrack sliderCaptchaTrack
|
||||
* @param sliderCaptchaValidData sliderCaptchaValidData
|
||||
* @param tolerant tolerant
|
||||
* @param type type
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证后
|
||||
*
|
||||
* @param sliderCaptchaTrack sliderCaptchaTrack
|
||||
* @param imageCaptchaTrack sliderCaptchaTrack
|
||||
* @param sliderCaptchaValidData sliderCaptchaValidData
|
||||
* @param tolerant tolerant
|
||||
* @param type type
|
||||
* @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;
|
||||
}
|
||||
|
||||
public boolean doValid(SliderCaptchaTrack sliderCaptchaTrack,
|
||||
public boolean doValid(ImageCaptchaTrack imageCaptchaTrack,
|
||||
Map<String, Object> sliderCaptchaValidData,
|
||||
Float tolerant,
|
||||
String type) {
|
||||
if (CaptchaUtils.isSliderCaptcha(type)) {
|
||||
// 滑动类型验证码
|
||||
return doValidSliderCaptcha(sliderCaptchaTrack, sliderCaptchaValidData, tolerant, type);
|
||||
return doValidSliderCaptcha(imageCaptchaTrack, sliderCaptchaValidData, tolerant, 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);
|
||||
@@ -209,13 +213,13 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
/**
|
||||
* 校验点选验证码
|
||||
*
|
||||
* @param sliderCaptchaTrack sliderCaptchaTrack
|
||||
* @param imageCaptchaTrack sliderCaptchaTrack
|
||||
* @param sliderCaptchaValidData sliderCaptchaValidData
|
||||
* @param tolerant tolerant
|
||||
* @param type type
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean doValidClickCaptcha(SliderCaptchaTrack sliderCaptchaTrack,
|
||||
public boolean doValidClickCaptcha(ImageCaptchaTrack imageCaptchaTrack,
|
||||
Map<String, Object> sliderCaptchaValidData,
|
||||
Float tolerant,
|
||||
String type) {
|
||||
@@ -224,12 +228,12 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
return false;
|
||||
}
|
||||
String[] splitArr = validStr.split(";");
|
||||
List<SliderCaptchaTrack.Track> trackList = sliderCaptchaTrack.getTrackList();
|
||||
List<ImageCaptchaTrack.Track> trackList = imageCaptchaTrack.getTrackList();
|
||||
if (trackList.size() < splitArr.length) {
|
||||
return false;
|
||||
}
|
||||
// 取出点击事件的轨迹数据
|
||||
List<SliderCaptchaTrack.Track> clickTrackList = trackList
|
||||
List<ImageCaptchaTrack.Track> clickTrackList = trackList
|
||||
.stream()
|
||||
.filter(t -> TrackTypeConstant.CLICK.equalsIgnoreCase(t.getType()))
|
||||
.collect(Collectors.toList());
|
||||
@@ -237,14 +241,14 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
return false;
|
||||
}
|
||||
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[] posArr = posStr.split(",");
|
||||
float xPercentage = Float.parseFloat(posArr[0]);
|
||||
float yPercentage = Float.parseFloat(posArr[1]);
|
||||
|
||||
float calcXPercentage = calcPercentage(track.getX(), sliderCaptchaTrack.getBgImageWidth());
|
||||
float calcYPercentage = calcPercentage(track.getY(), sliderCaptchaTrack.getBgImageHeight());
|
||||
float calcXPercentage = calcPercentage(track.getX(), imageCaptchaTrack.getBgImageWidth());
|
||||
float calcYPercentage = calcPercentage(track.getY(), imageCaptchaTrack.getBgImageHeight());
|
||||
|
||||
if (!checkPercentage(calcXPercentage, xPercentage, tolerant)
|
||||
|| !checkPercentage(calcYPercentage, yPercentage, tolerant)) {
|
||||
@@ -257,13 +261,13 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
/**
|
||||
* 校验滑动验证码
|
||||
*
|
||||
* @param sliderCaptchaTrack sliderCaptchaTrack
|
||||
* @param imageCaptchaTrack sliderCaptchaTrack
|
||||
* @param sliderCaptchaValidData sliderCaptchaValidData
|
||||
* @param tolerant tolerant
|
||||
* @param type type
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean doValidSliderCaptcha(SliderCaptchaTrack sliderCaptchaTrack,
|
||||
public boolean doValidSliderCaptcha(ImageCaptchaTrack imageCaptchaTrack,
|
||||
Map<String, Object> sliderCaptchaValidData,
|
||||
Float tolerant,
|
||||
String type) {
|
||||
@@ -272,11 +276,11 @@ public class SimpleImageCaptchaValidator implements ImageCaptchaValidator {
|
||||
// 没读取到百分比
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user