程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 后端开发

    • Spring Boot多模块项目开发
    • Spring Boot图片资源返回
    • Spring Boot文件上传
    • Spring Boot文件下载
    • 对接第三方文件上传
    • Servlet 原生API
    • HttpServletResponse 和 ResponseEntity
    • 后端解决跨域问题
    • 后端拦截器
    • SpringBoot+Vue实现邮件发送与验证码验证
    • 谷歌验证码
      • 1. 引入 Google Kaptcha 依赖
      • 2. 配置 Kaptcha 的基础设置
      • 3. 创建一个 CaptchaUtil 工具类
      • 4. 封装 Redis 存储验证码的逻辑
        • CaptchaService.java
      • 5. 创建 Controller 返回带 Base64 图片的验证码
        • CaptchaController.java
      • 6. 响应结果 AjaxResult.java
      • 7. 总结
    • 利用hutool工具类实现图片验证码
    • 统一返回格式
    • 通用 普通 登录模块
    • 通用 JWT 登录认证模块
    • 通用 普通 注册模块
    • 基于 MyBatis curd
    • 基于 MyBatis-Plus curd
    • Java 常见对象模型
    • 开发枚举的使用
    • MyBatis与MyBatis-Plus日期类型处理
    • 接口日志拦截基础版
    • 接口日志拦截进阶版
    • 文件操作工具类
    • Spring Boot 数据校验
    • 幂等性
  • 前端开发

  • 开发笔记
  • 后端开发
scholar
2024-12-27
目录

谷歌验证码

# 1. 引入 Google Kaptcha 依赖

在 pom.xml 文件中引入 Kaptcha 依赖:

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>
1
2
3
4
5

# 2. 配置 Kaptcha 的基础设置

可以通过 application.properties 或者 application.yml 对 Kaptcha 的一些基础设置进行配置,类似若依系统的配置。为了简洁,我们将配置放在代码中直接实现。

# 3. 创建一个 CaptchaUtil 工具类

CaptchaUtil 类封装了生成文本验证码和数学验证码(包括加减乘除运算)的逻辑,并且将验证码的 base64 格式返回,同时可以用来获取验证码结果以便存储到 Redis 中。

package com.example.util;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.util.Properties;
import java.util.Random;

@Component
public class GoogleCaptchaUtil {

    private DefaultKaptcha kaptcha;

    @PostConstruct
    public void init() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "no");
        properties.setProperty("kaptcha.textproducer.font.color", "black");
        properties.setProperty("kaptcha.image.width", "150");
        properties.setProperty("kaptcha.image.height", "50");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.char.space", "4");
        properties.setProperty("kaptcha.textproducer.font.size", "40");
        properties.setProperty("kaptcha.noise.color", "blue");

        Config config = new Config(properties);
        this.kaptcha = new DefaultKaptcha();
        this.kaptcha.setConfig(config);
    }

    /**
     * 生成文本验证码
     */
    public String createTextCaptcha() {
        return kaptcha.createText();
    }

    /**
     * 生成数学验证码,随机生成加减乘除运算
     */
    public MathCaptcha createMathCaptcha() {
        Random random = new Random();
        int num1 = random.nextInt(10) + 1;
        int num2 = random.nextInt(10) + 1;
        String[] operations = {"+", "-", "*", "/"};
        String operation = operations[random.nextInt(4)];

        int result;
        String captchaText;
        switch (operation) {
            case "+":
                result = num1 + num2;
                captchaText = num1 + " + " + num2;
                break;
            case "-":
                result = num1 - num2;
                captchaText = num1 + " - " + num2;
                break;
            case "*":
                result = num1 * num2;
                captchaText = num1 + " * " + num2;
                break;
            case "/":
                // 避免除数为0的情况
                num2 = num2 == 0 ? 1 : num2;
                result = num1 / num2;
                captchaText = num1 + " / " + num2;
                break;
            default:
                result = num1 + num2;
                captchaText = num1 + " + " + num2;
        }

        return new MathCaptcha(captchaText, result);
    }

    /**
     * 生成验证码图片
     */
    public BufferedImage createCaptchaImage(String text) {
        return kaptcha.createImage(text);
    }

    /**
     * 数学验证码内部类
     */
    public static class MathCaptcha {
        private final String captchaText;
        private final int answer;

        public MathCaptcha(String captchaText, int answer) {
            this.captchaText = captchaText;
            this.answer = answer;
        }

        public String getCaptchaText() {
            return captchaText;
        }

        public int getAnswer() {
            return answer;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

# 4. 封装 Redis 存储验证码的逻辑

为了便于后续的验证,我们将验证码答案存储到 Redis 中。这里用 RedisTemplate 进行简单的封装。

# CaptchaService.java

package com.example.service;

import com.example.util.CaptchaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;

@Service
public class CaptchaService {

    @Autowired
    private CaptchaUtil captchaUtil;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 生成文本验证码并存入 Redis
     */
    public BufferedImage generateTextCaptcha(String captchaKey) {
        String captchaText = captchaUtil.createTextCaptcha();
        // 将验证码答案存入 Redis,设置5分钟有效期
        redisTemplate.opsForValue().set(captchaKey, captchaText, 5, TimeUnit.MINUTES);
        // 生成验证码图片
        return captchaUtil.createCaptchaImage(captchaText);
    }

    /**
     * 生成数学验证码并存入 Redis
     */
    public BufferedImage generateMathCaptcha(String captchaKey) {
        CaptchaUtil.MathCaptcha mathCaptcha = captchaUtil.createMathCaptcha();
        // 将答案存入 Redis
        redisTemplate.opsForValue().set(captchaKey, mathCaptcha.getAnswer(), 5, TimeUnit.MINUTES);
        // 生成验证码图片
        return captchaUtil.createCaptchaImage(mathCaptcha.getCaptchaText());
    }

    /**
     * 验证验证码
     */
    public boolean validateCaptcha(String captchaKey, String inputCaptcha) {
        String cacheKey = "captcha:" + captchaKey;
        Object correctAnswer = redisTemplate.opsForValue().get(cacheKey);
        return correctAnswer != null && correctAnswer.toString().equals(inputCaptcha);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 5. 创建 Controller 返回带 Base64 图片的验证码

我们创建一个 CaptchaController 来提供 API,这个 API 会生成带有 uuid 和 Base64 的图片验证码。

# CaptchaController.java

package com.example.controller;

import com.example.service.CaptchaService;
import com.example.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.UUID;

@RestController
@RequestMapping("/captcha")
public class CaptchaController {

    @Autowired
    private CaptchaService captchaService;

    /**
     * 生成文本验证码,返回 uuid 和 base64 图片
     */
    @GetMapping("/text")
    public AjaxResult getTextCaptcha() throws IOException {
        String uuid = UUID.randomUUID().toString();
        BufferedImage image = captchaService.generateTextCaptcha(uuid);

        // 将图片转为 Base64
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", os);
        String base64Img = Base64.getEncoder().encodeToString(os.toByteArray());

        AjaxResult result = AjaxResult.success();
        result.put("uuid", uuid);
        result.put("img", "data:image/jpeg;base64," + base64Img);
        return result;
    }

    /**
     * 生成数学验证码,返回 uuid 和 base64 图片
     */
    @GetMapping("/math")
    public AjaxResult getMathCaptcha() throws IOException {
        String uuid = UUID.randomUUID().toString();
        BufferedImage image = captchaService.generateMathCaptcha(uuid);

        // 将图片转为 Base64
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", os);
        String base64Img = Base64.getEncoder().encodeToString(os.toByteArray());

        AjaxResult result = AjaxResult.success();
        result.put("uuid", uuid);
        result.put("img", "data:image/jpeg;base64," + base64Img);
        return result;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

# 6. 响应结果 AjaxResult.java

我们使用类似若依的 AjaxResult 格式返回数据。可以简单实现如下:

package com.example.util;

import java.util.HashMap;

public class AjaxResult extends HashMap<String, Object> {

    public static AjaxResult success() {
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("code", 200);
        ajaxResult.put("message", "操作成功");
        return ajaxResult;
    }

    public static AjaxResult error(String message) {
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("code", 500);
        ajaxResult.put("message", message);
        return ajaxResult;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 7. 总结

  • 验证码生成:支持生成文本和数学验证码。
  • Redis 存储:验证码的结果会被存储到 Redis 中,便

于后续验证。

  • API 响应:返回带有 uuid 和 Base64 格式的图片验证码,结构类似若依。
  • 支持校验:可以通过 uuid 和用户输入的值进行验证码验证。

这套流程完整地展示了如何在 Spring Boot 项目中通过 Kaptcha 生成验证码,并通过 Redis 实现验证。

编辑此页 (opens new window)
上次更新: 2025/03/16, 22:19:39
SpringBoot+Vue实现邮件发送与验证码验证
利用hutool工具类实现图片验证码

← SpringBoot+Vue实现邮件发送与验证码验证 利用hutool工具类实现图片验证码→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式