【瑞吉外卖】手机号验证码登录(用QQ邮件发送代替)
·
目录
介绍
本文介绍了QQ邮箱验证码登录功能的实现步骤:
- 获取QQ邮箱授权码并配置;
- 前端修改登录页面,增加验证码发送接口调用和登录逻辑;
- 后端实现包括:添加邮件依赖、配置邮件参数、开发验证码发送接口(使用随机4位数字)、登录验证逻辑(自动注册新用户)、邮件发送服务等。
重点使用了Spring Boot Mail组件实现邮件发送,通过Session存储验证码进行校验,并提供了完整的工具类生成随机验证码。系统实现了基于手机号和邮箱验证码的登录功能,包含自动注册新用户的能力。
一、获取授权码
生成授权码如下,最好截图保存,后续要用到
二、前端代码修改
2.1 调用发送验证码API接口,并取消自动填充验证码。代码位置:front/page/login.html
methods:{
getCode(){
this.form.code = ''
const regex = /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/;
if (regex.test(this.form.phone)) {
this.msgFlag = false
// this.form.code = (Math.random()*1000000).toFixed(0)
sendMsgApi({phone:this.form.phone})
}else{
this.msgFlag = true
}
},
async btnLogin(){
if(this.form.phone && this.form.code){
this.loading = true
// const res = await loginApi({phone:this.form.phone})
const res = await loginApi({phone:this.form.phone,code:this.form.code})
this.loading = false
if(res.code === 1){
sessionStorage.setItem("userPhone",this.form.phone)
window.requestAnimationFrame(()=>{
window.location.href= '/front/index.html'
})
}else{
this.$notify({ type:'warning', message:res.msg});
}
}else{
this.$notify({ type:'warning', message:'请输入手机号码'});
}
}
2.2 增加一个发送验证码API。代码位置:front/api/login.js
function loginApi(data) {
return $axios({
'url': '/employee/login',
'method': 'post',
data
})
}
三、后端代码修改
①pom依赖
<!--mail短信依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
②yml配置
这里需要配置【邮箱】和刚刚获取的【授权码】
spring:
mail:
host: smtp.qq.com
#发送验证码的邮箱
username: xxxxxxxxxxx@qq.com
# 你的QQ邮箱授权码
password: xxxxxxxxxxx
ssl:
enabled: true
③控制层
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private IUserService userService;
//获取验证码
@PostMapping("/sendMsg")
public R<String> sendMsg(HttpSession session, @RequestBody User user){
//获取邮箱号
//相当于发送短信定义的String to
String phone = user.getPhone();
String subject = "瑞吉外卖";
//StringUtils.isNotEmpty字符串非空判断
if (StringUtils.isNotEmpty(phone)) {
//发送一个四位数的验证码,把验证码变成String类型
String code = ValidateCodeUtils.generateValidateCode(4).toString();
String text = "【瑞吉外卖】您好,您的登录验证码为:" + code + ",请尽快登录";
log.info("验证码为:" + code);
//发送短信
userService.sendMsg(subject,text);
//将验证码保存到session当中
session.setAttribute(phone,code);
return R.success("验证码发送成功");
}
return R.error("验证码发送异常,请重新发送");
}
//登录
@PostMapping("/login")
//Map存JSON数据
public R<User> login(HttpSession session,@RequestBody Map map){
//获取邮箱,用户输入的
String phone = map.get("phone").toString();
//获取验证码,用户输入的
String code = map.get("code").toString();
//获取session中保存的验证码
Object sessionCode = session.getAttribute(phone);
//如果session的验证码和用户输入的验证码进行比对,&&同时
if (sessionCode != null && sessionCode.equals(code)) {
//要是User数据库没有这个邮箱则自动注册,先看看输入的邮箱是否存在数据库
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
//获得唯一的用户,因为手机号是唯一的
User user = userService.getOne(queryWrapper);
//要是User数据库没有这个邮箱则自动注册
if (user == null) {
user = new User();
user.setPhone(phone);
user.setStatus(1);
//取邮箱的前五位为用户名
user.setName(phone.substring(0,6));
userService.save(user);
}
//不保存这个用户名就登不上去,因为过滤器需要得到这个user才能放行,程序才知道你登录了
session.setAttribute("user", user.getId());
return R.success(user);
}
return R.error("登录失败");
}
}
④业务层
接口
public interface IUserService extends IService<User> {
void sendMsg(String subject,String text);
}
实现类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {
//把yml配置的邮箱号赋值到from
@Value("${spring.mail.username}")
private String email;
//发送邮件需要的对象
@Autowired
private JavaMailSender javaMailSender;
//邮件发送人
@Override
public void sendMsg(String subject, String text) {
//发送简单邮件,简单邮件不包括附件等别的
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(email);
message.setTo(email);
message.setSubject(subject);
message.setText(text);
//发送邮件
javaMailSender.send(message);
}
}
⑤工具类
ValidateCodeUtils.java,黑马给了此代码;不用 SMSUtils.java
package com.itheima.reggie.utils;
import java.util.Random;
/**
* 随机生成验证码工具类
*/
public class ValidateCodeUtils {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(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;
}
}
更多推荐
所有评论(0)