谷歌验证码
# 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
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
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
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
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
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)
上次更新: 2024/12/28, 18:32:08