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("验证码正确");
    }
}
相关推荐
毕设源码-朱学姐1 天前
【开题答辩全过程】以 基于JavaWeb的网上家具商城设计与实现为例,包含答辩的问题和答案
java
C雨后彩虹1 天前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
java1234_小锋1 天前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
2501_944525541 天前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐1 天前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
Filotimo_1 天前
Tomcat的概念
java·tomcat
索荣荣2 天前
Java Session 全面指南:原理、应用与实践(含 Spring Boot 实战)
java·spring boot·后端
Amumu121382 天前
Vue Router(二)
java·前端
念越2 天前
数据结构:栈堆
java·开发语言·数据结构