滑块验证码说明
滑块验证码
旋转验证码
滑动还原验证码
文字点选验证码
快速上手
注意: 如果你项目是使用的Springboot,
请使用SpringBoot脚手架工具tianai-captcha-springboot-starter;
该工具对验证码进行了封装,使其使用更加方便快捷
后端说明
引入Springboot脚手架依赖
<!-- maven导入 -->
<dependency><groupId>cloud.tianai.captcha</groupId><artifactId>tianai-captcha-springboot-starter</artifactId><version>1.4.1</version>
</dependency>
使用ImageCaptchaApplication生成和校验对象
package cloud.tianai.captcha.readme;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.spring.application.CaptchaImageType;
import cloud.tianai.captcha.spring.application.ImageCaptchaApplication;
import cloud.tianai.captcha.spring.vo.CaptchaResponse;
import cloud.tianai.captcha.spring.vo.ImageCaptchaVO;
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
import org.springframework.beans.factory.annotation.Autowired;public class Test2 {@Autowiredprivate ImageCaptchaApplication application;public void test() {// 1.生成滑块验证码(该数据返回给前端用于展示验证码数据)CaptchaResponse<ImageCaptchaVO> res1 = application.generateCaptcha(CaptchaTypeConstant.SLIDER);// 2.前端滑动完成后把数据传入后端进行校验是否通过, // 参数1: 生成的验证码对应的id, 由前端传过来// 参数2: 滑动轨迹验证码相关数据 ImageCaptchaTrack, 由前端传过来// 返回 match.isSuccess() 如果为true, 则验证通过ImageCaptchaTrack sliderCaptchaTrack = new ImageCaptchaTrack();ApiResponse<?> match = application.matching(res1.getId(), sliderCaptchaTrack);}
}
传统项目快速上手
引入依赖
<!-- maven 导入 -->
<dependency><groupId>cloud.tianai.captcha</groupId><artifactId>tianai-captcha</artifactId><version>1.4.1</version>
</dependency>
使用ImageCaptchaGenerator生成验证码
package example.readme;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.generator.impl.MultiImageCaptchaGenerator;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;
import cloud.tianai.captcha.validator.ImageCaptchaValidator;
import cloud.tianai.captcha.validator.impl.BasicCaptchaTrackValidator;import java.util.Map;public class Test {public static void main(String[] args) throws InterruptedException {ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();ImageCaptchaGenerator imageCaptchaGenerator = new MultiImageCaptchaGenerator(imageCaptchaResourceManager).init(true);/*生成滑块验证码图片, 可选项SLIDER (滑块验证码)ROTATE (旋转验证码)CONCAT (滑动还原验证码)WORD_IMAGE_CLICK (文字点选验证码)更多验证码支持 详见 cloud.tianai.captcha.common.constant.CaptchaTypeConstant*/ImageCaptchaInfo imageCaptchaInfo = imageCaptchaGenerator.generateCaptchaImage(CaptchaTypeConstant.SLIDER);// 负责计算一些数据存到缓存中,用于校验使用// ImageCaptchaValidator负责校验用户滑动滑块是否正确和生成滑块的一些校验数据; 比如滑块到凹槽的百分比值ImageCaptchaValidator imageCaptchaValidator = new BasicCaptchaTrackValidator();// 这个map数据应该存到缓存中,校验的时候需要用到该数据Map<String, Object> validMap = imageCaptchaValidator.generateImageCaptchaValidData(imageCaptchaInfo);}
}
ImageCaptchaInfo
为生成的验证码数据, validMap
为当前验证码的验证相关数据(该数据和当前生成的验证码数据绑定,后面校验该验证码是否通过的时候需要用到该数据)
注意: ImageCaptchaResourceManager,
ImageCaptchaGenerator,ImageCaptchaValidator
这些对象都是单例的,项目启动只需创建一次即可
使用ImageCaptchaValidator校验器 验证
package example.readme;import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
import cloud.tianai.captcha.validator.impl.BasicCaptchaTrackValidator;import java.util.Map;public class Test2 {public static void main(String[] args) {BasicCaptchaTrackValidator sliderCaptchaValidator = new BasicCaptchaTrackValidator();ImageCaptchaTrack imageCaptchaTrack = null;Map<String, Object> validMap = null;// 用户传来的行为轨迹和进行校验// - imageCaptchaTrack 为前端传来的滑动轨迹数据// - validMap 为生成验证码时缓存的validMap数据boolean check = sliderCaptchaValidator.valid(imageCaptchaTrack, validMap).isSuccess();}
}
ImageCaptchaTrack
为当前验证码行为轨迹相关数据
validMap
生成验证码时的验证码数据
SpringBoot脚手架扩展功能
yaml文件相关配置
# 滑块验证码配置, 详细请看 cloud.tianai.captcha.autoconfiguration.ImageCaptchaProperties 类
captcha:# 如果项目中使用到了redis,滑块验证码会自动把验证码数据存到redis中, 这里配置redis的key的前缀,默认是captcha:sliderprefix: captcha# 验证码过期时间,默认是2分钟,单位毫秒, 可以根据自身业务进行调整expire:# 默认缓存时间 2分钟default: 10000# 针对 点选验证码 过期时间设置为 2分钟, 因为点选验证码验证比较慢,把过期时间调整大一些WORD_IMAGE_CLICK: 20000# 使用加载系统自带的资源, 默认是 falseinit-default-resource: falsecache:# 缓存控制, 默认为false不开启enabled: true# 验证码会提前缓存一些生成好的验证数据, 默认是20cacheSize: 20# 缓存拉取失败后等待时间 默认是 5秒钟wait-time: 5000# 缓存检查间隔 默认是2秒钟period: 2000secondary:# 二次验证, 默认false 不开启enabled: false# 二次验证过期时间, 默认 2分钟expire: 120000# 二次验证缓存key前缀,默认是 captcha:secondarykeyPrefix: "captcha:secondary"
二次验证
如果 设置配置文件 captcha.secondary.enabled=true
时开启了二次验证
package cloud.tianai.captcha.readme;import cloud.tianai.captcha.spring.application.ImageCaptchaApplication;
import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;public class Test3 {@Autowiredprivate ImageCaptchaApplication sca;@GetMapping("/check2")@ResponseBodypublic boolean check2Captcha(@RequestParam("id") String id) {// 如果开启了二次验证if (sca instanceof SecondaryVerificationApplication) {return ((SecondaryVerificationApplication) sca).secondaryVerification(id);}return false;}
}
SprinBoot项目添加自定义模板/背景图片
通过扩展ResourceStore
接口添加自定义背景图片
添加模板使用 addTemplate(type1, template1)
方法, type1: 验证码类型, template1: 验证码模板相关数据
添加背景图片使用 addResource(type1, res1)
方法, type1: 验证码类型, res1: 验证码背景图片数据
package cloud.tianai.captcha.demo;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.generator.common.constant.SliderCaptchaConstant;
import cloud.tianai.captcha.generator.impl.StandardSliderImageCaptchaGenerator;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
import cloud.tianai.captcha.resource.impl.DefaultResourceStore;
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
import org.springframework.stereotype.Component;import static cloud.tianai.captcha.generator.impl.StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH;/*** @Author: 天爱有情* @date 2022/7/11 14:22* @Description 负责模板和背景图存储的地方*/
@Component
public class MyResourceStore extends DefaultResourceStore {public MyResourceStore() {// 滑块验证码 模板 (系统内置)ResourceMap template1 = new ResourceMap("default",4);template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/active.png")));template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/fixed.png")));ResourceMap template2 = new ResourceMap("default",4);template2.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/active.png")));template2.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/fixed.png")));// 旋转验证码 模板 (系统内置)ResourceMap template3 = new ResourceMap("default",4);template3.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/active.png")));template3.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, StandardSliderImageCaptchaGenerator.DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/3/fixed.png")));// 1. 添加一些模板addTemplate(CaptchaTypeConstant.SLIDER, template1);addTemplate(CaptchaTypeConstant.SLIDER, template2);addTemplate(CaptchaTypeConstant.ROTATE, template3);// 2. 添加自定义背景图片addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/a.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/b.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/c.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/d.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/e.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/g.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/h.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/i.jpg","default"));addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/j.jpg","default"));addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/48.jpg","default"));addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/48.jpg","default"));addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/c.jpg","default"));}
}
依赖于 tianai-captcha 的高扩展性, 可以自定义 如下实现 然后直接注入到spring中即可替换默认实现,实现自定义扩展
生成器(ImageCaptchaGenerator
) – 主要负责生成滑块验证码所需的图片
校验器(ImageCaptchaValidator
) – 主要负责校验用户滑动的行为轨迹是否合规
资源管理器(ImageCaptchaResourceManager
) – 主要负责读取验证码背景图片和模板图片等
资源存储(ResourceStore
) – 负责存储背景图和模板图
资源提供者(ResourceProvider
) – 负责将资源存储器中对应的资源转换为文件流
滑块应用程序(ImageCaptchaApplication
) ,上面一些接口的组合和增强,比如负责把验证的数据存到缓存中,用户一般直接使用这个接口方便的生成滑块图片和校验数据
其它扩展
添加自定义图片资源
package example.readme;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.ResourceStore;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
import cloud.tianai.captcha.resource.impl.provider.URLResourceProvider;public class Test5 {public static void main(String[] args) {ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();// 通过资源管理器或者资源存储器ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();// 添加classpath目录下的 aa.jpg 图片resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource(ClassPathResourceProvider.NAME, "/aa.jpg"));// 添加远程url图片资源resourceStore.addResource(CaptchaTypeConstant.SLIDER,new Resource(URLResourceProvider.NAME, "http://www.xx.com/aa.jpg"));// 内置了通过url 和 classpath读取图片资源,如果想扩展可实现 ResourceProvider 接口,进行自定义扩展}
}
添加自定义模板资源
系统内置了2套模板,可以到QQ群:1021884609 文件中获取更多模板或者自己制作模板
模板图片格式
滑块验证码
滑块大小为 110*110
格式为png
凹槽大小为 110*110
格式为png
旋转验证码
滑块大小为 200*200
格式为png
凹槽大小为 200*200
格式为png
package example.readme;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.generator.common.constant.SliderCaptchaConstant;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.ResourceStore;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;public class Test6 {public static void main(String[] args) {ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();// 通过资源管理器或者资源存储器ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();// 添加滑块验证码模板.模板图片由三张图片组成ResourceMap template1 = new ResourceMap("default", 4);template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/active.png"));template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/fixed.png"));resourceStore.addTemplate(CaptchaTypeConstant.SLIDER, template1);// 模板与三张图片组成 滑块、凹槽、背景图// 同样默认支持 classpath 和 url 两种获取图片资源, 如果想扩展可实现 ResourceProvider 接口,进行自定义扩展}
}
清除内置的图片资源和模板资源
package example.readme;import cloud.tianai.captcha.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.generator.impl.MultiImageCaptchaGenerator;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;public class Test6 {public static void main(String[] args) {ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();ImageTransform imageTransform = new Base64ImageTransform();//为方便快速上手 系统本身自带了一张图片和两套滑块模板,如果不想用系统自带的可以不让它加载系统自带的// 第二个构造参数设置为false时将不加载默认的图片和模板ImageCaptchaGenerator imageCaptchaGenerator = new MultiImageCaptchaGenerator(imageCaptchaResourceManager, imageTransform).init(false);}
}
自定义 imageCaptchaValidator 校验器
/ 该接口负责对用户滑动验证码后传回的数据进行校验,比如滑块是否滑到指定位置,滑块行为轨迹是否正常等等
// 该接口的默认实现有
// SimpleImageCaptchaValidator 校验用户是否滑到了指定缺口处
// BasicCaptchaTrackValidator 是对 SimpleImageCaptchaValidator增强
// BasicCaptchaTrackValidator是对SimpleImageCaptchaValidator的增强 对滑动轨迹进行了简单的验证
// 友情提示 因为BasicCaptchaTrackValidator 里面校验滑动轨迹的算法已经开源,有强制要求的建议重写该接口的方法,避免被破解
自定义 ResourceProvider 实现自定义文件读取策略,
比如 oss之类的
package example.readme;import cloud.tianai.captcha.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.generator.impl.MultiImageCaptchaGenerator;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.ResourceProvider;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;import java.io.InputStream;public class Test7 {public static void main(String[] args) {// 自定义 ResourceProviderResourceProvider resourceProvider = new ResourceProvider() {@Overridepublic InputStream getResourceInputStream(Resource data) {return null;}@Overridepublic boolean supported(String type) {return false;}@Overridepublic String getName() {return null;}};ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();ImageTransform imageTransform = new Base64ImageTransform();ImageCaptchaGenerator imageCaptchaGenerator = new MultiImageCaptchaGenerator(imageCaptchaResourceManager,imageTransform).init(false);// 注册imageCaptchaResourceManager.registerResourceProvider(resourceProvider);}
}
对StandardImageCaptchaGenerator
增加缓存模块
由于实时生成滑块图片可能会有一点性能影响,内部基于StandardSliderCaptchaGenerator
进行了提前缓存生成好的图片,CacheSliderCaptchaGenerator
这只是基本的缓存逻辑,比较简单,用户可以定义一些更加有意思的扩展,用于突破性能瓶颈
package example.readme;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo;
import cloud.tianai.captcha.generator.impl.CacheImageCaptchaGenerator;
import cloud.tianai.captcha.generator.impl.MultiImageCaptchaGenerator;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;public class Test8 {public static void main(String[] args) throws InterruptedException {// 使用 CacheSliderCaptchaGenerator 对滑块验证码进行缓存,使其提前生成滑块图片// 参数一: 真正实现 滑块的 SliderCaptchaGenerator// 参数二: 默认提前缓存多少个// 参数三: 出错后 等待xx时间再进行生成// 参数四: 检查时间间隔ImageCaptchaResourceManager imageCaptchaResourceManager = new DefaultImageCaptchaResourceManager();ImageTransform imageTransform = new Base64ImageTransform();ImageCaptchaGenerator imageCaptchaGenerator = new CacheImageCaptchaGenerator(new MultiImageCaptchaGenerator(imageCaptchaResourceManager, imageTransform), 10, 1000, 100);imageCaptchaGenerator.init(true);// 生成滑块图片ImageCaptchaInfo slideImageInfo = imageCaptchaGenerator.generateCaptchaImage(CaptchaTypeConstant.SLIDER);// 获取背景图片的base64String backgroundImage = slideImageInfo.getBackgroundImage();// 获取滑块图片String sliderImage = slideImageInfo.getSliderImage();System.out.println(slideImageInfo);}
}
前端说明
原生HTML使用方法
导入tac.min.js
和tac.css
和jquery
<link href="styles/tac.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="tac.min.js"></script>
创建一个div快用于渲染验证码
<div id="captcha-box"></div>
在需要调用验证码的时候执行加载验证码方法
const config = {// 生成接口 (必选项,必须配置, 要符合tianai-captcha默认验证码生成接口规范) 参考 https://gitee.com/tianai/tianai-captcha-demorequestCaptchaDataUrl: "/gen",// 验证接口 (必选项,必须配置, 要符合tianai-captcha默认验证码校验接口规范) 参考 https://gitee.com/tianai/tianai-captcha-demovalidCaptchaUrl: "/check",// 验证码绑定的div块 (必选项,必须配置)bindEl: "#captcha-box",// 验证成功回调函数(必选项,必须配置)validSuccess: (res, c, tac) => {// todo 这里res为后端返回的数据,一般返回验证成功的token, 进行登录或其它操作时,要把返回的token传给后端进行二次验证console.log("验证成功,后端返回的数据为", res);// 调用登录方法进行登录 这里login登录方法为自己的登录函数this.login(res.captchaToken)// 销毁验证码服务tac.destroyWindow();},// 验证失败的回调函数(可忽略,如果不自定义 validFail 方法时,会使用默认的)validFail: (res, c, tac) => {// 验证失败后重新拉取验证码tac.reloadCaptcha();}
}
// 创建 TAC 启动验证码服务,调用该方法后会在指定的div块中渲染出验证码
new TAC(config).init();
VUE2使用方法
导入tac.min.js
和tac.css
和jquery
后和原生使用方法调用即可
<template><div class="login-div"><div class="kuang"><span class="kuang-left">用户名</span>天爱有情</div><div class="kuang"><span class="kuang-left">密码</span>*********</div><div id="login-btn" @click="loginBtn">登录</div><div id="captcha-div"></div></div>
</template><script>import "@/assets/captcha/css/tac.css" // 验证码cssimport "@/assets/captcha/js/jquery.min.js"; // 验证码jsimport "@/assets/captcha/js/tac.min.js"; // 验证码jsexport default {methods: {loginBtn() {// 样式配置const config = {requestCaptchaDataUrl: "http://localhost:8083/gen/random",validCaptchaUrl: "http://localhost:8083/check3",bindEl: "#captcha-div",// 验证成功回调函数validSuccess:(res,c,tac)=> {this.login();tac.destroyWindow();}}new window.TAC(config).init();},login() {alert("登录成功")}}}
</script>
其它框架使用方法
导入写好的tac.min.js
和tac.css
即可, 或者把该项目复制到自己项目用使用即可
一些扩展功能
去除或者替换默认的logo
let config ={...}
let style = {logoUrl: null}// 去除logo
//let style = {logoUrl: "/xx/xx/xxx.png"}// 替换成自定义的logo
new TAC(config,style).init();
对滑块的按钮和背景设置为自定义的一些样式
// 这里分享一些作者自己调的样式供参考
const style = {// 按钮样式btnUrl: "https://minio.tianai.cloud/public/captcha-btn/btn3.png",// 背景样式bgUrl: "https://minio.tianai.cloud/public/captcha-btn/btn3-bg.jpg",// logo地址logoUrl: "https://minio.tianai.cloud/public/static/captcha/images/logo.png",// 滑动边框样式moveTrackMaskBgColor: "#f7b645",moveTrackMaskBorderColor: "#ef9c0d"}
new TAC(config,style).init();