Spring:邮箱验证码

Spring:邮箱验证码

既然谈到了邮箱验证码,肯定是我们后端通过某些操作把验证码发送到用户的邮箱里。
我们首先讲解Spring如何发送邮箱
其实我之前已经写过了一篇文章:
实现Spring发送邮件 - 云端的解构者 | 西行寺岩羊的博客
请先阅读这篇文章,然后按照文章的操作对Spring进行配置。
配置好之后,我们就拿到了发送邮件接口。

这里我把MailService贴出来供大家参考

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
@Service  
public class MailService {
@Autowired
private JavaMailSenderImpl javaMailSender;
@Value("${spring.mail.username}")
private String sendMailer;
/**
* 检测邮件信息类
* @param to 发送人
* @param subject 主题
* @param text 内容
*/
private void checkMail(String to,String subject,String text){
if(StringUtils.isEmpty(to)){
throw new RuntimeException("邮件收信人不能为空");
}
if(StringUtils.isEmpty(subject)){
throw new RuntimeException("邮件主题不能为空");
}
if(StringUtils.isEmpty(text)){
throw new RuntimeException("邮件内容不能为空");
}
}
public void sendHtmlMailMessage(String to,String subject,String text){
checkMail(to,subject,text);
try {
//true 代表支持复杂的类型
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
//邮件发信人
mimeMessageHelper.setFrom(sendMailer);
//邮件收信人 1或多个
mimeMessageHelper.setTo(to.split(","));
//邮件主题
mimeMessageHelper.setSubject(subject);
//邮件内容
mimeMessageHelper.setText(text,true);
//邮件发送时间
mimeMessageHelper.setSentDate(new Date());

//发送邮件
javaMailSender.send(mimeMessageHelper.getMimeMessage());
System.out.println("发送邮件成功:"+sendMailer+"->"+to);

} catch (MessagingException e) {
e.printStackTrace();
System.out.println("发送邮件失败:"+e.getMessage());
}
}

这一段Service代码是针对html格式的邮箱内容进行编写的,没错,邮箱支持HTML格式,而且很多平台发送邮箱验证码都是使用这种格式,比如大家最喜欢的 Steam 平台。
如果大家需要纯文本格式的邮件发送代码,请参考上面我之前写的一篇文章。
我对邮件发送的Service已经封装好了,在Controller层可以直接拿来就用。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**  
* 发送HTML邮箱验证码
* @param to 邮箱
*/
@RequestMapping("/sendMailCaptcha")
public void sendHtmlMailMessage(String to) {
String subject = "曦光录";
//生成验证码
String code = generateSixDigitCode();
redisUtil.set(to + "code", code, 1);
String content = "邮箱内容";
mailService.sendHtmlMailMessage(to, subject, content);
}

请看这段代码,我首先调用了一个生成验证码的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
public class GetCaptcha {
private static final String CHARACTERS = "0123456789";
/**
* @return 六位的随机验证码字符串。
*/
public static String generateSixDigitCode() {
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 6; i++) {
// 从CHARACTERS中随机选择一个字符
int index = random.nextInt(CHARACTERS.length());
char randomChar = CHARACTERS.charAt(index);
sb.append(randomChar);
}
return sb.toString();
}
}

这里注意看,我们在class的上方使用了@Component,如果大家不认识它,那么就参考
[[Spring:整体思路讲解#^78644d|@Component]]
曦光录登录模块概述 - 云端的解构者 | 西行寺岩羊的博客
CTRL+F搜索:UserService是怎么被发现的?

上文中的Controller代码中使用了一个重要的模块—— Redis
redisUtil.set(to + "code", code, 1);

Redis的基础介绍和应用请参考
[[Spring:Redis]]
Spring:Redis - 云端的解构者 | 西行寺岩羊的博客
Redis文章和接下来的内容可能有些许重复
实例
直接看这个罢(懒

代码在实例中已经有了,讲讲思路
在上文代码中我们已经实现了:

  • 生成验证码
  • 以HTML的形式把验证码发送到用户邮箱里
  • 以「用户id+code:验证码」的形式存储到Redis中

那么,该如何验证呢?

我们可以把验证码和用户的登录或者注册信息一并发送到后端,比如

1
2
3
4
5
6
7
8
{
user:{
name:zheep,
password:114514,
...
}
code:10086
}

这样后端在接收到数据后,在Service层中,先对验证码进行校验:

1
2
3
4
5
6
7
8
9
10
11
12
String redisCode = redisUtil.get(userDTO.getEmail() + "code", new TypeReference<String>() {});  
// 校验验证码
if (code.isEmpty()) {
throw new BaseException("请输入验证码");
}
if (redisUtil.get(redisCode) == null){
throw new BaseException("验证码已过期");
}
if (!code.equals(redisCode)) {
throw new BaseException("验证码错误");
}
redisUtil.delete(redisCode)

Spring:邮箱验证码
https://www.zheep.top/posts/1626624342/
作者
西行寺岩羊
发布于
2025年5月8日
许可协议