1. 为什么需要图形验证码
在Web应用中,图形验证码是一种常见的安全防护手段。它的核心作用是区分人类用户和自动化程序(如爬虫、暴力破解工具等)。我经历过多个项目因为缺乏验证码保护而被恶意刷接口的情况,轻则服务器资源被耗尽,重则导致数据泄露。
图形验证码之所以有效,是因为它利用了计算机视觉的局限性。虽然现代OCR技术已经相当先进,但针对扭曲、干扰线、背景噪声等设计的验证码仍然能有效阻挡大部分自动化攻击。在SpringBoot项目中实现验证码功能,可以为注册、登录、敏感操作等场景增加一道安全屏障。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 验证码实现方案选型
在Java生态中,实现图形验证码主要有以下几种方案:
-
自研绘制:使用Java原生AWT/Swing或BufferedImage手动绘制
- 优点:完全可控,可高度定制
- 缺点:开发成本高,安全性难以保证
-
Kaptcha:Google开源的验证码库
- 优点:配置简单,功能完善
- 缺点:样式较为固定,扩展性一般
-
Hutool-Captcha:Hutool工具包中的验证码模块
- 优点:API简洁,支持多种验证码类型
- 缺点:功能相对基础
经过对比,对于大多数SpringBoot项目,我推荐使用Hutool实现。它不仅轻量易用,还能与SpringBoot完美集成。下面我们就基于Hutool来实现一个完整的验证码解决方案。
3. 环境准备与基础配置
3.1 添加Hutool依赖
首先在pom.xml中添加Hutool的starter依赖:
xml复制<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
注意:建议使用最新稳定版,可以通过Maven中央仓库查询最新版本号。Hutool的版本兼容性很好,基本不会出现版本冲突问题。
3.2 验证码参数配置
在application.yml中添加验证码相关配置:
yaml复制captcha:
width: 130
height: 48
codeCount: 5
lineCount: 150
expireSeconds: 180
这些参数分别控制:
- width/height:验证码图片尺寸
- codeCount:验证码字符数量
- lineCount:干扰线数量
- expireSeconds:验证码有效期(秒)
4. 核心实现代码
4.1 验证码生成服务
创建CaptchaService类:
java复制@Service
public class CaptchaService {
@Value("${captcha.width}")
private int width;
@Value("${captcha.height}")
private int height;
@Value("${captcha.codeCount}")
private int codeCount;
@Value("${captcha.lineCount}")
private int lineCount;
@Value("${captcha.expireSeconds}")
private int expireSeconds;
public CaptchaVO generateCaptcha() {
// 创建线形干扰的验证码
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height, codeCount, lineCount);
String code = captcha.getCode();
String imageBase64 = captcha.getImageBase64();
// 实际项目中应该将验证码存入Redis
String uuid = UUID.randomUUID().toString();
RedisUtil.setEx(CacheKey.CAPTCHA_KEY + uuid, code, expireSeconds);
return new CaptchaVO(uuid, imageBase64);
}
public boolean validate(String uuid, String inputCode) {
String cacheCode = RedisUtil.get(CacheKey.CAPTCHA_KEY + uuid);
