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("验证码正确");
    }
}
相关推荐
aircrushin22 分钟前
OpenClaw“养龙虾”现象的社会技术学分析
前端·后端
37手游后端团队27 分钟前
全网最简单!从零开始,轻松把 openclaw 小龙虾装回家
人工智能·后端·openai
用户83071968408229 分钟前
Spring Boot WebClient性能比RestTemplate高?看完秒懂!
java·spring boot
Apifox44 分钟前
测试数据终于不用到处复制了,Apifox 自动化测试新增「共用测试数据」
前端·后端·测试
Gardener1721 小时前
OpenStack Instance ID 映射机制详解
后端
无责任此方_修行中2 小时前
拒绝 AI 焦虑!一个普通程序员的真实 AI 工作流(附成本账单)
后端·程序员·ai编程
Assby2 小时前
从洋葱模型看Java与Go的设计哲学:为什么它们如此不同?
java·后端·架构
命运石之门的选择2 小时前
Flink 并行度调优"黄金三步法"
后端
泰式大师2 小时前
在 AI Agent 场景下,我们如何优雅地处理长文本?
后端