平台奖励创作,可能会升级VIP文章,可以移步我的公众号:【编程朝花夕拾】,且可获取首发内容。
01 引言
上一期介绍了传统的图片验证码的使用,这一期我们继续行为验证码的介绍。
行为验证码的目前被广大用户喜爱,因为用户使用起来更加方便,既能满足安全的校验,又能保证用户使用的便利。各大厂商也推出了自己的行为验证码,并有偿对外开放API,如腾讯、网易等。
今天要介绍的是来自国内顶级社区 dromara
下的tianai-captcha
(天爱验证码(TAC))。
02 TAC简介
作者表示该验证码可能是java界最好的开源行为验证码 tianai-captcha
,包括了 滑块验证码、点选验证码、行为验证码、旋转验证码, 滑动验证码等。
给Gitee
托管平台有3.4K的Star
,在GitHub
上也有813的Star
。
Gitee地址:https://gitee.com/dromara/tianai-captcha/
GitHub地址:https://github.com/dromara/tianai-captcha
03 项目实战
官方使用文档:http://doc.captcha.tianai.cloud/
本次案例使用流行的SpringBoot
项目。
3.1 Maven依赖引入
<dependency>
<groupId>cloud.tianai.captcha</groupId>
<artifactId>tianai-captcha-springboot-starter</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3.2 配置文件
# 使用加载系统自带的资源, 默认是 false(这里系统的默认资源包含 滑动验证码模板/旋转验证码模板,如果想使用系统的模板,这里设置为true)
captcha.init-default-resource=true
# 配置字体包,供文字点选验证码使用,可以配置多个,不配置使用默认的字体
captcha.font-path=classpath:META-INF/fonts/SIMSUN.TTC
SIMSUN.TTC
字体是Maven依赖包里面的字体,主要用来点击字体。
其他配置可以不用配置,使用默认值即可。
详细配置:
http://doc.captcha.tianai.cloud/#spring-boot%E9%A1%B9%E7%9B%AE
3.3 服务端配置
服务端的配置这个很重要,加载图片模板资源。
@Component
public class CaptchaResourceConfiguration {
@Autowired
private ResourceStore resourceStore;
@PostConstruct
public void init() {
// 自定义图片
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/a.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/11.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/48.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/11.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/48.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/12.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/c.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/13.jpg", "default"));
}
}
分别加载SLIDER
、ROTATE
、CONCAT
、WORD_IMAGE_CLICK
类型的背景图。Maven中也提供了一个图片,但是同样需要在这里配置。
上面的配置的图片均放在项目中bgimages
的文件夹下:
不配置这个调用就会报错:
这里要吐槽一下,作者如果内置一组图片资源,让用户直接使用就更好了。
3.4 服务端生成行为验证码
@RequestMapping("/genCaptcha")
@ResponseBody
public CaptchaResponse<ImageCaptchaVO> genCaptcha(@RequestParam(value = "type", required = false)String type) {
if (StringUtils.isBlank(type)) {
type = CaptchaTypeConstant.SLIDER;
}
CaptchaResponse<ImageCaptchaVO> response = imageCaptchaApplication.generateCaptcha(type);
return response;
}
通过Type
控制是滑动、旋转、拼接还是点击文字。
3.5 行为验证
@lombok.Data
public static class Data {
private String id;
private ImageCaptchaTrack data;
}
@PostMapping("/check")
@ResponseBody
public ApiResponse<?> checkCaptcha(@RequestBody Data data) {
ApiResponse<?> response = imageCaptchaApplication.matching(data.getId(), data.getData());
if (response.isSuccess()) {
return ApiResponse.ofSuccess(Collections.singletonMap("id", data.getId()));
}
return response;
}
校验行为验证的结果。
3.6 二次验证
/**
* 二次验证,一般用于机器内部调用,这里为了方便测试
* @param id id
* @return boolean
*/
@GetMapping("/check2")
@ResponseBody
public boolean check2Captcha(@RequestParam("id") String id) {
// 如果开启了二次验证
if (imageCaptchaApplication instanceof SecondaryVerificationApplication) {
return ((SecondaryVerificationApplication) imageCaptchaApplication).secondaryVerification(id);
}
return false;
}
这个是出于安全的考虑。页面验证通过,处理业务逻辑时需要二次验证保证操作安全。这里的二次验证需要配置,默认不开启。
# 二次验证, 默认false 不开启
captcha.secondary.enabled=true
# 二次验证过期时间, 默认 2分钟
captcha.secondary.expire=120000
# 二次验证缓存key前缀,默认是 captcha:secondary
captcha.keyPrefix: "captcha:secondary"
3.7 页面初始化
页面的主要代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>行为验证码</title>
<!-- 样式 -->
<link rel="stylesheet" href="/css/tac.css">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<!-- js -->
<script src="/js/tac.min.js"></script>
<style>
...
</style>
</head>
<body>
<div>
<ul class="top">
<li onclick="openCaptcha('SLIDER')">滑块验证码</li>
<li onclick="openCaptcha('ROTATE')">旋转验证码</li>
<li onclick="openCaptcha('CONCAT')">滑动还原验证码</li>
<li onclick="openCaptcha('WORD_IMAGE_CLICK')">点选验证码</li>
</ul>
<div id="captcha-box"></div>
</div>
<script>
let globalTAC;
const config = {
// 生成接口
requestCaptchaDataUrl: "/tac/genCaptcha",
// 验证接口
validCaptchaUrl: "/tac/check",
// 验证码绑定的div块
bindEl: "#captcha-box",
// 验证成功回调函数
validSuccess: (res, c, tac) => {
// 销毁验证码服务
tac.destroyWindow();
// 调用登录方法
this.login(res.data.id);
}
}
const style = {
// 配置样式, logoURL地址
// logoUrl: "/images/11.jpg"
logoUrl: "/images/11.jpg"
}
function login(token) {
// 在执行登录时,将验证码token传过去进行二次校验
$.get("/tac/check2?id=" + token, (res) => {
alert("登录成功")
})
}
// 初始化
$(function () {
// 创建 TAC 启动验证码服务
globalTAC = new TAC(config, style).init();
})
// 切换验证码类型
function openCaptcha(type) {
if (globalTAC) {
globalTAC.destroyWindow();
}
config.requestCaptchaDataUrl = "/tac/genCaptcha?type="+type
globalTAC = new TAC(config, style).init();
}
</script>
</body>
</html>
3.8 测试
前端的接入还可以使用sdk:
04 小结
以上就是行为验证码的内容。除了该项目,还有另一个开源的验证码项目,感兴趣的可以去了解一下:
https://github.com/anji-plus/captcha