这是我参与「第四届青训营 」笔记创作活动的的第十五天
写在前面
在写大项目时,在用户登录模块,我们选择邮箱验证码登录,所以特此记录邮箱验证码登录的后端代码实现
引入依赖
<!-- 1.邮箱依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.7.2</version>
</dependency>
<!-- 2.模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 3.validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 4.HuTool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 说明
2.模板引擎是用于美化发送的邮件样式- 本邮件验证登录以qq邮箱作为发送箱,因此需要引入qq邮箱官网的依赖支持
3.validation
配置
spring:
mail:
host: smtp.qq.com
username: # 用来发送邮件的邮箱账号
password: # 授权码
default-encoding: UTF-8
redis:
database: 1
host: 127.0.0.1
port: 6379
password: # 密码
- 说明
- 需要登录自己的邮箱账号,在
设置-账户-POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务那开启POP3/SMTP服务,同时获取授权码 - 引入redis数据库是为了保存用户的验证码
- 需要登录自己的邮箱账号,在
使用实例
- util,用于生成验证码
public class VerificationCodeUtil {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer getVerificationCode(int length){
Integer code =null;
if(length == 4){
code = new Random().nextInt(9999);//生成随机数,最大为9999
if(code < 1000){
code = code + 1000;//保证随机数为4位数字
}
}else if(length == 6){
code = new Random().nextInt(999999);//生成随机数,最大为999999
if(code < 100000){
code = code + 100000;//保证随机数为6位数字
}
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length){
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
- controller层
@PostMapping("/sendMsg")
public ResultVo<String> sendMsg(@RequestBody User user, HttpSession session){
String email = user.getPhone();
if (email == null) {
throw new GlobalException(new CodeMsg("邮箱为空"));
}
log.info(email);
// 获取发送邮箱验证码的HTML模板
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template",
TemplateConfig.ResourceMode.CLASSPATH));
Template template = engine.getTemplate("email-code.ftl");
//获取验证码
Integer code = VerificationCodeUtil.getVerificationCode(6);
//发送验证码
userService.send(new EmailRo(email, "邮箱验证码登录", template.render(Dict.create().set("code", code)), code));
return ResultVo.success("验证码发送成功");
}
- service层
//获取配置文件的信息
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
//sprintboot整合redis
@Resource
private RedisTemplate<String,Object> redisTemplate;
public void send(EmailRo emailRo) {
//设置
MailAccount account = new MailAccount();
account.setHost(host);
// 设置发送人信息
account.setFrom("xxx" + "<" + username + ">");
// 设置发送人名称
account.setUser(username);
// 设置发送授权码
account.setPass(password);
account.setAuth(true);
// ssl方式发送
account.setSslEnable(true);
// 使用安全连接
account.setStarttlsEnable(true);
//发送邮件
try {
Mail.create(account)
.setTos(emailRo.getEmail())
.setTitle(emailRo.getSubject())
.setContent(emailRo.getContent())
.setHtml(true)
//关闭session
.setUseGlobalSession(false)
.send();
//将验证码保存到redis
redisTemplate.opsForValue().set(emailRo.getEmail(), emailRo.getCode(),120, TimeUnit.SECONDS);
} catch (Exception e){
throw new GlobalException(new CodeMsg("邮件发送失败"));
}
}
- 模板文件
email-code.ftl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>
@page {
margin: 0;
}
</style>
</head>
<body>
<div class="header">
<div style="padding: 10px;padding-bottom: 0px;">
<p style="margin-bottom: 10px;padding-bottom: 0px;">尊敬的用户,您好:</p>
<p style="text-indent: 2em; margin-bottom: 10px;">您正在申请邮箱验证,您的验证码为:</p>
<p class="code-text">${code}</p>
<div class="footer">
</div>
</div>
</div>
</body>
</html>
<style lang="css">
body {
margin: 0px;
padding: 0px;
font: 100% SimSun, Microsoft YaHei, Times New Roman, Verdana, Arial, Helvetica, sans-serif;
color: #000;
}
.header {
height: auto;
width: 820px;
min-width: 820px;
margin: 0 auto;
margin-top: 20px;
border: 1px solid #eee;
}
.code-text {
text-align: center;
font-family: Times New Roman;
font-size: 22px;
color: #C60024;
padding: 20px 0px;
margin-bottom: 10px;
font-weight: bold;
background: #ebebeb;
}
.footer {
margin: 0 auto;
z-index: 111;
width: 800px;
margin-top: 30px;
border-top: 1px solid #DA251D;
}
</style>
写在最后
以上便是我的一些学习笔记,若有不足,欢迎指出