您好,登录后才能下订单哦!
# SpringBoot配置Google Kaptcha验证码图片生成工具
## 一、验证码技术概述
验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart"的缩写,即全自动区分计算机和人类的图灵测试。在Web应用中,验证码主要用于:
1. 防止恶意注册和登录
2. 防止暴力破解
3. 防止自动化脚本攻击
4. 保护系统免受垃圾信息侵扰
Google Kaptcha是一个简单实用的验证码生成库,具有以下特点:
- 高度可配置的验证码样式
- 支持文本、数字和算术表达式
- 易于与Spring框架集成
- 良好的扩展性
## 二、环境准备
### 1. 创建SpringBoot项目
使用Spring Initializr创建项目,选择以下依赖:
- Spring Web
- Thymeleaf (可选,用于前端展示)
### 2. 添加Kaptcha依赖
在`pom.xml`中添加Kaptcha依赖:
```xml
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
创建配置类KaptchaConfig.java
:
@Configuration
public class KaptchaConfig {
@Bean
public Producer kaptchaProducer() {
Properties properties = new Properties();
// 图片宽度
properties.setProperty("kaptcha.image.width", "150");
// 图片高度
properties.setProperty("kaptcha.image.height", "50");
// 文本集合,验证码值从此集合中获取
properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 字体
properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
// 干扰线颜色
properties.setProperty("kaptcha.noise.color", "gray");
// 图片样式
properties.setProperty("kaptcha.obscurificator.impl",
"com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
参数名称 | 默认值 | 说明 |
---|---|---|
kaptcha.border | yes | 图片边框 |
kaptcha.border.color | black | 边框颜色 |
kaptcha.image.width | 200 | 图片宽度 |
kaptcha.image.height | 50 | 图片高度 |
kaptcha.textproducer.char.string | abcde2345678gfynmnpwx | 验证码字符集 |
kaptcha.textproducer.char.length | 5 | 验证码长度 |
kaptcha.textproducer.font.names | Arial | 字体 |
kaptcha.textproducer.font.size | 40px | 字体大小 |
kaptcha.textproducer.font.color | black | 字体颜色 |
kaptcha.noise.impl | com.google.code.kaptcha.impl.DefaultNoise | 干扰实现类 |
kaptcha.noise.color | black | 干扰颜色 |
kaptcha.background.clear.from | lightGray | 背景渐变起始色 |
kaptcha.background.clear.to | white | 背景渐变结束色 |
@Controller
public class KaptchaController {
@Autowired
private Producer kaptchaProducer;
@GetMapping("/captcha.jpg")
public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException {
// 设置响应头
response.setContentType("image/jpeg");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 生成验证码文本
String capText = kaptchaProducer.createText();
// 将验证码存入session
session.setAttribute("captcha", capText);
// 生成验证码图片并写入响应
try (OutputStream out = response.getOutputStream()) {
BufferedImage bi = kaptchaProducer.createImage(capText);
ImageIO.write(bi, "jpg", out);
out.flush();
}
}
@PostMapping("/verify")
@ResponseBody
public String verify(@RequestParam String code, HttpSession session) {
String captcha = (String) session.getAttribute("captcha");
if (code.equalsIgnoreCase(captcha)) {
return "验证码正确";
}
return "验证码错误";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Kaptcha Demo</title>
</head>
<body>
<form action="/verify" method="post">
<img src="/captcha.jpg" onclick="this.src='/captcha.jpg?'+Math.random()"
style="cursor: pointer;" title="点击刷新验证码"/>
<br/>
<input type="text" name="code" placeholder="请输入验证码"/>
<button type="submit">验证</button>
</form>
</body>
</html>
实现com.google.code.kaptcha.GimpyEngine
接口可以自定义验证码样式:
public class CustomGimpy implements GimpyEngine {
@Override
public BufferedImage getDistortedImage(BufferedImage baseImage) {
// 自定义图片扭曲逻辑
Graphics2D graph = baseImage.createGraphics();
// 添加自定义效果...
return baseImage;
}
}
然后在配置中指定:
properties.setProperty("kaptcha.obscurificator.impl", "com.your.package.CustomGimpy");
@Bean
public Producer mathKaptcha() {
Properties properties = new Properties();
// 使用算术表达式
properties.setProperty("kaptcha.textproducer.impl",
"com.google.code.kaptcha.text.impl.MathTextCreator");
// 算式结果长度
properties.setProperty("kaptcha.textproducer.char.length", "1");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
对于分布式系统,建议使用Redis存储验证码:
@Autowired
private RedisTemplate<String, String> redisTemplate;
@GetMapping("/captcha.jpg")
public void getCaptcha(HttpServletResponse response,
@RequestParam String uuid) throws IOException {
// ...生成验证码代码...
// 存入Redis,设置5分钟过期
redisTemplate.opsForValue().set("captcha:" + uuid, capText, 5, TimeUnit.MINUTES);
// ...生成图片代码...
}
@PostMapping("/verify")
@ResponseBody
public String verify(@RequestParam String code,
@RequestParam String uuid) {
String captcha = redisTemplate.opsForValue().get("captcha:" + uuid);
// ...验证逻辑...
}
使用Spring AOP或拦截器限制验证码获取频率:
@Aspect
@Component
public class RateLimitAspect {
private final Map<String, Long> lastRequestTime = new ConcurrentHashMap<>();
@Around("execution(* com..KaptchaController.getCaptcha(..)) && args(..,request)")
public Object limit(ProceedingJoinPoint pjp, HttpServletRequest request) throws Throwable {
String ip = request.getRemoteAddr();
Long lastTime = lastRequestTime.get(ip);
long current = System.currentTimeMillis();
if (lastTime != null && current - lastTime < 60000) {
throw new RuntimeException("请求过于频繁,请稍后再试");
}
lastRequestTime.put(ip, current);
return pjp.proceed();
}
}
可能原因: - 未正确配置Content-Type响应头 - 图片生成过程中出现异常 - 浏览器缓存问题
解决方案:
- 确保设置了response.setContentType("image/jpeg")
- 添加随机参数防止缓存:/captcha.jpg?t=123456
- 检查后台日志是否有异常
解决方案: - 增加干扰线和噪点 - 使用更复杂的字符集 - 实现动态字符间距和旋转 - 定期更换验证码样式
解决方案: - 使用Redis集中存储验证码 - 确保session共享配置正确 - 考虑使用JWT等无状态验证方式
本文详细介绍了如何在SpringBoot项目中集成Google Kaptcha验证码组件,包括:
通过合理配置和适当的安全措施,Kaptcha可以成为Web应用安全防护的有效工具。开发者应根据实际业务需求调整验证码的复杂度,在安全性和用户体验之间取得平衡。
提示:在实际项目中,建议将验证码与登录/注册流程的其他安全措施(如IP限制、密码强度检查等)结合使用,构建多层次的安全防护体系。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。