一、前言
在我们进行注册、登录等操作的时候,为了保证用户信息的安全性,我们经常会需要接收短信验证码等场景,虽然它的安全系数较高,但是由于需要付费使用,所以我们也可以使用邮箱服务接收验证码来实现安全校验,提升系统安全系数。
二、环境准备
以QQ邮箱为例,我们需要在邮箱中开启SMTP服务获取授权码。
点击生成授权码。
三、SpringBoot集成
1.引入依赖
<!--QQ邮箱验证码所需jar包-->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.创建邮件发送的控制层
package com.example.nettyserverdemo.controller;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
/**
* @author qx
* @date 2023/12/29
* @des 邮件发送控制层
*/
@RestController
public class EmailController {
@GetMapping("/getCode")
public void sendMail(@RequestParam("targetEmail") String targetEmail) throws EmailException {
// 生成6位随机验证码
String code = String.valueOf(new Random().nextInt(899999) + 100000);
SimpleEmail email = new SimpleEmail();
// 设置发送邮件的服务器
email.setHostName("smtp.qq.com");
String myEmail = "136xxxxxx@qq.com";
email.setAuthentication(myEmail, "xxxxxxxxx");
// 发送者邮箱
email.setFrom(myEmail);
// 用于接收验证码的邮箱
email.addTo(targetEmail);
// 邮件的主题
email.setSubject("注册验证码");
// 邮件的内容
email.setMsg("您的验证码为:" + code + "(一分钟有效)");
// 发送邮件
email.send();
}
}
启动程序,我们先简单测试一下看看邮箱是否接收到验证码。
我们在接收的邮箱中发现确实收到了验证码的邮件。
3.优化
上面我们提到了验证码在一分钟内有效,那么我们就需要设置在这个时间内,我们不能频繁去请求邮箱获取验证码。我们就需要使用Redis来优化我们的代码。
package com.example.nettyserverdemo.controller;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* @author qx
* @date 2023/12/29
* @des 邮件发送控制层
*/
@RestController
public class EmailController {
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("/getCode")
public String sendMail(@RequestParam("targetEmail") String targetEmail) throws EmailException {
// 获取redis中指定邮箱为key的数据
String redisCode = redisTemplate.opsForValue().get(targetEmail);
if (redisCode == null) {
// 生成6位随机验证码
String code = String.valueOf(new Random().nextInt(899999) + 100000);
// 验证码保存到redis中 接收邮箱为key,验证码为值 有效期为1分钟
redisTemplate.opsForValue().set(targetEmail, code, 1, TimeUnit.MINUTES);
SimpleEmail email = new SimpleEmail();
// 设置发送邮件的服务器
email.setHostName("smtp.qq.com");
String myEmail = "13xxxxxx3@qq.com";
email.setAuthentication(myEmail, "xxxxxxx");
// 发送者邮箱
email.setFrom(myEmail);
// 用于接收验证码的邮箱
email.addTo(targetEmail);
// 邮件的主题
email.setSubject("注册验证码");
// 邮件的内容
email.setMsg("您的验证码为:" + code + "(一分钟有效)");
// 发送邮件
email.send();
return "验证码发送成功";
}
return "请勿重复发送验证码";
}
}
我们重新启动程序继续进行测试。我们短时间内频繁请求获取邮箱验证码会提示错误。
1分钟后我们继续测试,由于redis中的数据过期了,所以又重新获取到了验证码并发送到指定的邮箱。