目录
- 前言
- [1. 复用验证码](#1. 复用验证码)
- [2. 源码解读](#2. 源码解读)
-
- [2.1 先走DefaultCaptchaServiceImpl类](#2.1 先走DefaultCaptchaServiceImpl类)
- [2.2 核心ClickWordCaptchaServiceImpl类](#2.2 核心ClickWordCaptchaServiceImpl类)
- [3. 具体使用](#3. 具体使用)
前言
对于Java的基本知识推荐阅读:
对于源码可以直接使用:anji-plus/AJ-Captcha
1. 复用验证码
下载源码之后,配置好Maven项目,直接启用Springboot的项目
对应修改前端的启动网址配置:
最终截图如下:
2. 源码解读
通过断点,具体走一遍完整逻辑
具体请求地址走向如下:
对应check中的Service类:ResponseModel check(CaptchaVO captchaVO);
先跳入DefaultCaptchaServiceImpl类:
之后检查相应的类型:(校验传入的CaptchaVO对象,并根据验证码类型调用相应的服务进行验证)
从CaptchaServiceFactory中获取对应验证码类型的服务实例
单看它的工厂类:
- 使用ServiceLoader动态加载所有实现了CaptchaCacheService和CaptchaService接口的类
- 将加载到的服务实例存储在cacheService和instances这两个Map中,键为各自服务的类型(由type()或captchaType()方法返回)
- 记录日志,输出支持的验证码缓存服务和验证码类型服务
总体就是map的实例化对象,通过key value
2.1 先走DefaultCaptchaServiceImpl类
基本的配置类主要由两个大配置类组成
对应的配置类走向设置:
配置类配置默认值:
对应的参数如下:
但是我的默认值不是DefaultCaptchaServiceImpl么,对应只需要在源码中再次设置即可
2.2 核心ClickWordCaptchaServiceImpl类
实现了验证码的初始化、生成、校验和验证等功能
- 读取配置:从配置文件中读取字体类型、字体大小等配置
- 初始化字体:根据配置文件中指定的字体类型和大小,初始化字体对象
- 异常处理:如果字体加载失败,记录错误日志
- 生成图片:调用ImageUtils.getPicClick()生成点击验证码图片
- 检查图片有效性:如果图片未初始化成功或获取的图片数据无效,返回错误信息
- 返回结果:将生成的图片数据返回给前端
- 获取缓存中的验证码数据:从缓存中获取验证码对应的坐标信息,并删除缓存记录。
- 解析坐标数据:将坐标信息进行解密并解析成坐标对象。
- 验证坐标信息:检查用户点击的坐标是否与生成验证码时的坐标匹配。
- 异常处理:如果解析失败或坐标不匹配,返回错误信息。
- 成功处理:将验证成功的信息存入缓存,并返回成功结果
总体就是:
- 初始化:从配置文件中读取字体和其他配置信息,初始化验证码生成所需的资源
- 生成验证码:生成点击文字验证码图片,并返回给前端
- 校验验证码:从缓存中获取验证码的坐标信息,解析并验证用户点击的坐标是否正确
- 验证验证码:二次验证时,从缓存中获取并验证验证码信息,确保验证码的唯一性和时效性
3. 具体使用
由于自身的项目使用已经引入,大致细节如下:
可结合他人教程阅读:行为验证码(AJ-Captcha快速入门)
引入依赖包:
xml
<!--验证码-->
<dependency>
<groupId>com.github.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId>
<version>1.2.7</version>
</dependency>
默认依赖就存在 CaptchaController类,可以不用写
只需复制前端所有内容即可
如果需要重写对应的后端,关键内容是
还有图片的导入以及路径的修改:
再次解读下这个方法:
java
public static final String getRemoteId(HttpServletRequest request) {
String xfwd = request.getHeader("X-Forwarded-For");
String ip = getRemoteIpFromXfwd(xfwd);
String ua = request.getHeader("user-agent");
if (StringUtils.isNotBlank(ip)) {
return ip + ua;
}
return request.getRemoteAddr() + ua;
}
getRemoteId 方法负责拼接客户端的 IP 地址和用户代理(User-Agent)信息
这些信息将用于生成或校验验证码时的上下文信息,以增加验证码的安全性