文章目录
- 一:前台功能实现
- 1.1 页面编写
- 1.2 发送验证码——sendEmailCode
- 1.2.1 远程调用发送接口
- 1.2.1 接口防刷校验——60s内只能发送一次
- 二:获取QQ邮箱授权码
- 2.1 登录QQ邮箱
- 2.2 开启SMTP权限
- 2.2.1 设置
- 2.2.2 账户
- 2.2.3 管理服务
- 2.2.4 生成授权码
- 2.2.5 复制授权码
- 三:后台功能实现
- 3.1 编写配置文件
- 3.2 发送验证码工具类
- 3.3 验证码防刷校验——60s内不允许再次发送
- 3.4 通过验证码登录
一:前台功能实现
1.1 页面编写
<el-form id="emailForm" size="medium">
<el-row>
<el-col :span="24">
<el-form-item class="icon1" label="邮箱:" prop="email">
<el-input placeholder="邮箱" id="email" style="width: 80%;" v-model="emailForm.email" type="text"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item class="icon1" label="验证码:" prop="checkCode">
<el-input type="text" id="checkCode" v-model="emailForm.checkCode" style="width: 45%;" placeholder="验证码"></el-input>
<a @click="sendEmailCode" id="sendEmailCode" >邮箱验证码</a>
</el-form-item>
</el-col>
</el-row>
</el-form>
1.2 发送验证码——sendEmailCode
1.2.1 远程调用发送接口
/**
* 发送邮箱验证码
*/
sendEmailCode(){
/**
* 1.给指定邮箱发送验证码
* 2.添加验证码倒计时功能
*/
//判断有没有正在进行倒计时操作
if($(this).hasClass("disabled")){
//正在倒计时
} else {
//给指定的手机发送验证码
let email = this.emailForm.email;
$.get("/sendEmail?email=" + email);
this.timeoutChangeStyleEmail();
}
},
1.2.1 接口防刷校验——60s内只能发送一次
timeoutChangeStyleEmail(){
$("#sendEmailCode").attr("class","disabled");
if( this.num == 0){
$("#sendEmailCode").text("发送验证码");
this.num = 60;
$("#sendEmailCode").attr("class","");
} else {
let str = this.num + "s 后再次发送";
$("#sendEmailCode").text(str);
setTimeout(() => {
this.timeoutChangeStyleEmail();
}, 1000);
}
this.num--;
},
二:获取QQ邮箱授权码
2.1 登录QQ邮箱
https://wx.mail.qq.com/
2.2 开启SMTP权限
主页->设置->账户->管理服务
2.2.1 设置
2.2.2 账户
2.2.3 管理服务
2.2.4 生成授权码
2.2.5 复制授权码
三:后台功能实现
3.1 编写配置文件
spring:
mail:
host: smtp.qq.com #给QQ邮箱发送邮件
username: ##你的QQ邮箱
password: ###你刚才复制的授权码##
port: 465
protocol: smtp
default-encoding: utf-8
properties:
mail:
# 开启 debug,这样方便开发者查看邮件发送日志
debug: true
smtp:
auth: true
starttls:
enable: true
required: true
ssl:
enable: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
3.2 发送验证码工具类
package com.sysg.user.utils;
import com.sysg.base.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Random;
/**
* 发送邮件验证码
*/
@Component
@Slf4j
public class EmailUtil {
@Autowired
private JavaMailSender javaMailSender;
/**
* 读取yml文件中username的值并赋值给sendUserEmail
*/
@Value("${spring.mail.username}")
private String sendUserEmail;
/**
* 发送邮件验证码
* @param emailReceiver
* @return
*/
public String sendSimpleMail(String emailReceiver) {
// 构建一个邮件对象
SimpleMailMessage message = new SimpleMailMessage();
// 设置邮件发送者
message.setFrom(sendUserEmail);
// 设置邮件接收者
message.setTo(emailReceiver);
// 设置邮件的主题
message.setSubject("登录验证码");
// 设置邮件的正文
Random random = new Random();
StringBuilder code = new StringBuilder();
for (int i = 0; i < 6; i++) {
int r = random.nextInt(10);
code.append(r);
}
String text = "您的验证码为:" + code + ",请勿泄露给他人。";
message.setText(text);
// 发送邮件
try {
javaMailSender.send(message);
log.info("邮件发送成功");
return code.toString();
} catch (MailException e) {
e.printStackTrace();
log.info("邮件发送失败");
return StringUtils.EMPTY;
}
}
}
此时就收到验证码了
3.3 验证码防刷校验——60s内不允许再次发送
public R sendEmail(String email) {
try {
//1.接口防刷,防止同一个手机号60s内再次发送
//UserConstant.EMAIL_CODE_CACHE_PREFIX自行去定义
String redisEmailCode = stringRedisTemplate.opsForValue().get(UserConstant.EMAIL_CODE_CACHE_PREFIX + email);
if(!StringUtils.isEmpty(redisEmailCode)){
long redisDate = Long.parseLong(redisEmailCode.split("_")[1]);
if(System.currentTimeMillis() - redisDate < 60000){
//60秒内不可以再发
return R.error("获取验证码过于频繁,请您稍后再试");
}
}
String emailCode = emailUtil.sendSimpleMail(email);
String dateEmailCode = emailCode + "_" + System.currentTimeMillis();
//2.验证码的再次校验,存储到redis中。key-email,value-code
//key——"code:15648961564" value-564986
//保存到redis里面,并设置10分钟超时时间
stringRedisTemplate.opsForValue().set(UserConstant.EMAIL_CODE_CACHE_PREFIX + email,dateEmailCode,10, TimeUnit.MINUTES);
return R.ok("验证码发送成功");
} catch (NumberFormatException e) {
e.printStackTrace();
return R.error("验证码发送失败");
}
}
3.4 通过验证码登录
public R emailLogin(EmailLoginVo vo, HttpSession session) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("email",vo.getEmail());
User user = userDao.selectOne(wrapper);
if( user == null){
return R.error(500, "当前邮箱没有注册,请注册后在使用");
}
String token = null;
//1.校验验证码
String code = vo.getCheckCode();
String s = stringRedisTemplate.opsForValue().get(UserConstant.EMAIL_CODE_CACHE_PREFIX + vo.getEmail());
if(!StringUtils.isEmpty(s)){
if(code.equals(s.split("_")[0])){
//校验完成以后删除验证码
stringRedisTemplate.delete(UserConstant.EMAIL_CODE_CACHE_PREFIX + vo.getEmail());
//验证码校验通过,登录成功
String username = user.getUsername();
//生成token
token = JwtUtil.createToken(username);
if(token != null){
//将数据存储到session对象中
session.setAttribute("user",username);
return R.ok(200, "登录成功",token);
}else{
return R.error(400, "登录失败");
}
} else {
return R.error("验证码错误");
}
} else {
//验证码不存在的话,就说明过期了
return R.error("验证码错误");
}
}
此时功能就实现了!!!