随着互联网的发展,网站用户的管理、触达、消息通知成为一个网站设计是否合理的重要标志。目前主流互联网公司都支持手机验证码注册、登录。但是手机短信作为服务端网站是需要付出运营商通信成本的,而邮箱的注册、登录、重置密码,无疑成为了这一问题的最佳解决方案,那么如何通过VUE+SPRINGBOOT实现邮箱网站用户的注册、登录、重置密码呢?下面直接说明效果和代码实现。体验网址点击可以访问:whitehttps://wdfgdzx.top/login
一、VUE注册界面,核心逻辑在邮箱正则验证+邮箱验证码发送与存储。
<template>
<div class="Register-container">
<div class="allClass">
<div class="titleClass"><b>没有账号请邮箱注册</b></div>
<el-form :rules="ruleList" :model="user" ref="userForm"><!--用来校验表单-->
<el-form-item prop="name"><!--必须el-form-item prop="xxx"才能生效-->
<el-input placeholder="请输入您的邮箱" size="medium" class="inputOneClass" prefix-icon="el-icon-message"
v-model="user.name" autocomplete="new-password"></el-input>
</el-form-item>
<el-form-item prop="code"><!--邮箱获取的验证码,放置非法注册-->
<el-input placeholder="邮箱收到的验证码" size="medium" class="inputOneClass" prefix-icon="el-icon-lock"
v-model="user.code" style="width: 188px;"></el-input>
<el-button type="primary" size="medium" class="ml-10" @click="getEmailCode">获取验证码</el-button>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="请设置密码" size="medium" class="inputOneClass" prefix-icon="el-icon-lock"
v-model="user.password"
show-password autocomplete="new-password"></el-input>
</el-form-item>
<div class="buttonClass">
<el-button type="primary" size="medium" autocomplete="off" @click="registerClick">注册用户</el-button>
<el-button type="warning" size="medium" autocomplete="off" @click="$router.push('/login')">返回登录
</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script>
export default {
name: "Register",
data() {
return {
user: {},
ruleList: { // 在return的第一级别写
name: [
{required: true, message: '请输入您的邮箱账号', trigger: 'blur'},
{min: 3, max: 20, message: '长度在3-9个字符', trigger: 'blur'}
],
password: [
{required: true, message: '请设置密码', trigger: 'blur'},
{min: 3, max: 20, message: '长度在3-20个字符', trigger: 'blur'}
],
code: [
{required: true, message: '请输入收到的验证码', trigger: 'blur'},
{min: 3, max: 20, message: '长度在3-20个字符', trigger: 'blur'}
]
}
}
},
methods: {
getEmailCode() {
if (!this.user.name) {
this.$message.warning("请输入邮箱账号")
return
}
if (!/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/.test(this.user.name)) {
this.$message.warning("请输入正确的邮箱账号")
return
}
// 都通过请求发送邮箱验证码---name的值其实就是用户邮箱
this.$http.post("/big/email_code", this.user).then(res => {
if (res.data.code === "200") {
this.$message.success("邮箱验证码发送成功,请到对应邮箱查看")
} else {
this.$message.error(res.data.message)
}
})
},
/*点击登录*/
registerClick() {
this.$refs["userForm"].validate(valid => {
if (valid) { // 表单校验合法
this.$http.post("/big/register", this.user).then(res => { // 调用后端注册方法
// console.log(res.data)
if (res.data.code === "200") {
this.$router.push("/login")
this.$message.success("注册成功,请登录!")
} else {
this.$message.error(res.data.message)
}
});
}
})
}
}
}
</script>
<style scoped>
.Register-container {
height: 100vh;
background-image: linear-gradient(to bottom right, deepskyblue, darkcyan);
overflow: hidden;
}
.allClass {
margin: 200px auto;
background-color: #ffffff;
width: 350px;
height: 400px;
padding: 20px;
border-radius: 10px;
}
.titleClass {
margin: 20px 0;
text-align: center;
font-size: 24px;
}
.inputOneClass {
margin: 10px 0;
}
.buttonClass {
margin: 10px 0;
text-align: right;
}
</style>
二、后端发送与存储逻辑
@PostMapping("/email_code") // 也需要配置可以直接访问
public Res email_code(@RequestBody User user) {
if (StringUtils.isBlank(user.getName())) {
return Res.error(Constants.CODE_400, "参数错误");
}
QueryWrapper<Email> emailQueryWrapper = new QueryWrapper<>();
emailQueryWrapper.eq("email", user.getName());
Email existEmail = emailMapper.selectOne(emailQueryWrapper);
Date nowTime = new Date();
long diffLongTime = 0L;
if (existEmail != null && existEmail.getSendTime() != null) { // 首次注册必为空
diffLongTime = nowTime.getTime() - existEmail.getSendTime().getTime(); // 所以如果为空则直接放行,不为空在这里获取时间差距
if (diffLongTime <= (5 * 60 * 1000)) {
return Res.error(Constants.CODE_600, "您的验证码5分钟内有效,请到您的邮箱查看验证码,或者请您5分钟后再获取。");
}
}
// 发送邮箱验证码
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom("wdfgdzx@126.com"); // 这个发件人必须设置,和配置的一样
Date sendDate = new Date();
simpleMailMessage.setSentDate(sendDate);
simpleMailMessage.setSubject("【人人都有人工智能注册验证码】");
String code = RandomUtil.randomNumbers(4);
simpleMailMessage.setText("您本次邮箱注册的验证码是:【" + code + "】,请妥善保管,切勿泄露。");
simpleMailMessage.setTo(user.getName()); // 用户输入的邮箱
Email emailEntity = new Email();
emailEntity.setEmail(user.getName());
emailEntity.setCode(code);
emailEntity.setSendTime(sendDate);
if (existEmail == null) { // 验证码存储与更新逻辑
emailMapper.insert(emailEntity); // 不存在则插入
} else {
emailMapper.update(emailEntity, emailQueryWrapper); // 存在则升级code,根据邮箱名称升级
}
javaMailSender.send(simpleMailMessage);
return Res.success(null); // 返回200即可
}
@PostMapping("/register")
public Res register(@RequestBody User user) {
User existUser;
// 比对验证码
QueryWrapper<Email> emailQueryWrapper = new QueryWrapper<>();
emailQueryWrapper.eq("email", user.getName());
Email existEmail = emailMapper.selectOne(emailQueryWrapper);
if (existEmail != null && !existEmail.getCode().equals(user.getCode())) {
// System.err.println(existEmail.getCode());
// System.err.println(existEmail.getCode() == null);
if (existEmail.getCode().isEmpty()) {
return Res.error(Constants.CODE_600, "验证码已经失效,请重新获取验证码");
} else {
return Res.error(Constants.CODE_600, "验证码验证失败,请检查验证码是否填写正确");
}
}
if (existEmail != null && (existEmail.getCode() != null)) {
existEmail.setCode("");
emailMapper.updateById(existEmail);
}
try {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.eq("name", user.getName());
existUser = userMapper.selectOne(userQueryWrapper); // 新技术
// existUser = userMapper.selectUserByName(user);
} catch (Exception e) { // 如果系统中存在多条等异常情况
e.printStackTrace();
return Res.error(Constants.CODE_500, "系统错误");
}
if (existUser != null) {
return Res.error(Constants.CODE_600, "用户名已经存在,请更换用户名");
}
user.setNick("人工智能-热爱者"); // 默认的昵称
user.setRole("人工智能"); // 默认角色
user.setPassword(MyUtils.getSHA256StrJava(user.getPassword())); // 密码用SHA256加密存储
user.setAvatar("https://wdfgdzx.top:3333/document/cd39af3e175b4524890c267e07298f5b.png"); // 设置默认头像,这个每次需要变动的 发布V1.0后再修改
userMapper.insert(user); // 不存在,开始插入到数据库
return Res.success(null); // 返回200即可
}