kaptcha 验证码生成工具在springboot中集成

今天分享一个生成验证码的工具kaptcha 。

Kaptcha 是 Google 开发的一个简单实用的验证码生成库,基于 javax.imageio 实现,配置灵活,易于集成到 Spring/Spring Boot 项目中。

maven项目中依赖

复制代码
<!-- Maven 依赖 -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

springboot中集成:

首先需要定义一个DefaultKaptcha的bean,用于生成验证码的图片和文字配置。以下是两个经典的案例(实际应用中可以根据需要设置纯数字或者算式,我们项目中只是生成的纯数字比较简单,我们是生成之后输出前端,然后存入redis中生成uuid做为验证批次号。验证时候前端传回来用户输的和uuid在redis中进行匹配,这个比较简单)下面直接上代码

复制代码
@Configuration
public class KaptchaConfig {
    
    @Bean
    public DefaultKaptcha defaultKaptcha() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        
        // 图片样式配置
        properties.setProperty("kaptcha.border", "yes"); // 有边框
        properties.setProperty("kaptcha.border.color", "105,179,90"); // 边框颜色
        properties.setProperty("kaptcha.image.width", "160"); // 宽度
        properties.setProperty("kaptcha.image.height", "60"); // 高度
        
        // 文本配置
        properties.setProperty("kaptcha.textproducer.font.color", "blue"); // 字体颜色
        properties.setProperty("kaptcha.textproducer.font.size", "35"); // 字体大小
        properties.setProperty("kaptcha.textproducer.char.length", "4"); // 字符个数
        properties.setProperty("kaptcha.textproducer.char.space", "3"); // 字符间距
        properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier"); // 字体
        
        // 干扰配置
        properties.setProperty("kaptcha.noise.color", "red"); // 干扰线颜色
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise"); // 干扰实现
        
        // 背景配置
        properties.setProperty("kaptcha.background.clear.from", "white"); // 背景渐变开始
        properties.setProperty("kaptcha.background.clear.to", "white"); // 背景渐变结束
        
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
    
    // 数学算式验证码配置(如:1+2=?)
    @Bean
    public DefaultKaptcha mathKaptcha() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        
        properties.setProperty("kaptcha.image.width", "160");
        properties.setProperty("kaptcha.image.height", "60");
        properties.setProperty("kaptcha.textproducer.font.size", "35");
        
        // 使用数学算式文本生成器
        properties.setProperty("kaptcha.textproducer.impl", 
            "com.xxx.MathTextCreator"); // 自定义类
        
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

controller实现

复制代码
@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    
    @Autowired
    private DefaultKaptcha defaultKaptcha;
    
    /**
     * 生成验证码图片
     */
    @GetMapping("/image")
    public void getCaptcha(HttpServletRequest request, 
                          HttpServletResponse response) throws IOException {
        // 设置响应头
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", 
            "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        
        // 生成验证码文本
        String captchaText = defaultKaptcha.createText();
        
        // 存储到Session(推荐使用Redis存储分布式应用)
        request.getSession().setAttribute("CAPTCHA_SESSION_KEY", captchaText);
        
        // 可选:存储到Redis(分布式场景)或者生成UUID传给前端
         String sessionId = request.getSession().getId();
        redisTemplate.opsForValue().set(
            "captcha:" + sessionId, 
           captchaText, 
            5, TimeUnit.MINUTES
        );
        
        // 生成图片并写出
        BufferedImage image = defaultKaptcha.createImage(captchaText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
    
    /**
     * 验证码验证
     */
    @PostMapping("/verify")
    public ApiResult verifyCaptcha(@RequestParam String code,
                                   HttpServletRequest request) {
        // 从Session获取验证码
        String sessionCaptcha = (String) request.getSession()
            .getAttribute("CAPTCHA_SESSION_KEY");
        
        // 从Redis获取(分布式场景)
        String sessionId = request.getSession().getId();
         String redisCaptcha = redisTemplate.opsForValue()
            .get("captcha:" + sessionId);
        
        if (StringUtils.isBlank(sessionCaptcha)) {
            return ApiResult.error("验证码已失效");
        }
        
        if (StringUtils.isBlank(code)) {
            return ApiResult.error("请输入验证码");
        }
        
        if (!sessionCaptcha.equalsIgnoreCase(code.trim())) {
            return ApiResult.error("验证码错误");
        }
        
        // 验证成功后清除验证码
        request.getSession().removeAttribute("CAPTCHA_SESSION_KEY");
        redisTemplate.delete("captcha:" + sessionId);
        //处理后续登陆操作
        return ApiResult.success("验证码正确");
    }
}
相关推荐
mikelv012 小时前
实现返回树状结构小记
java·数据结构
Duang007_2 小时前
【LeetCodeHot100 超详细Agent启发版本】两数之和 (Two Sum)
java·人工智能·python
色空大师2 小时前
maven引入其他项目依赖爆红
java·maven
yangminlei2 小时前
深入理解Sentinel:分布式系统的流量守卫者
java
JavaEdge.2 小时前
java.io.IOException: Previous writer likely failed to write hdfs报错解决方案
java·开发语言·hdfs
w***76552 小时前
存储技术全景:从基础原理到未来趋势
spring boot·后端·mybatis
J_liaty2 小时前
基于ip2region.xdb数据库从IP获取到属地解析全攻略
java·网络·后端
沛沛老爹2 小时前
Web转AI架构篇:Agent Skills vs MCP-混合架构设计模式实战指南
java·前端·人工智能·架构·llm·rag
独自破碎E2 小时前
Java的CMS垃圾回收流程
java·开发语言