一、前期准备:
1、下载安装redis
在这里附上我自己用的redis版本,用其他版本的可以自己去找资源,百度网盘链接:https://pan.baidu.com/s/1WPAksWV-Vi8vDZz_i2YI5w
提取码:ovxd
首先解压到一个文件,然后双击redies-server.exe即可运行redis。
2、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3、准备一个邮件.
1、我使用的是163,找到设置,点击POP3这里。
2、开启这两项服务,记住弹出的一串大写字母,后面要配置的。
往下拉还有服务器地址,配置的时候赋值给host
二、后端配置
在application.properties中配置
# 配置邮箱服务器,账号密码等
spring.mail.host=smtp.163.com
spring.mail.username= XXXXXXXXX@163.com
spring.mail.password= XXXXXXXXXXXX(授权码)
redis用的默认配置,没有额外配。
如果你的配置文件是application.yml,那么使用如下代码配置
# 配置邮箱服务器,账号密码等
spring:
mail:
host: smtp.163.com
username: XXXXXXXX@163.com
password: XXXXXXXXXXXX(授权码)
三、前端代码
点击忘记密码后跳转忘记密码页面。忘记密码页面及代码如下:
<template>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="auto" class="login-container"
:hide-required-asterisk="true">
<h3 class="login_title">重置密码</h3>
<el-form-item label="用户名:" prop="username">
<el-input v-model="ruleForm.username"></el-input>
</el-form-item>
<el-form-item label="验证码:" prop="code">
<el-row>
<el-col span="16"><el-input type="code" v-model="ruleForm.code"></el-input></el-col>
<el-col span="6"><el-button style="background: #13bbf4; color: #ffffff" :loading="ruleForm.loading"
@click="getCode">获取验证码
</el-button></el-col>
</el-row>
</el-form-item>
<el-form-item label="密 码:" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="确认密码:" prop="password">
<el-input type="password" v-model="ruleForm.checkPassword" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button style="width: 100%; background: #13bbf4; color: #ffffff" :loading="ruleForm.loading"
@click="resetPassword">重置密码
</el-button>
</el-form-item>
</el-form>
</template>
<script>
import {ElMessage} from "element-plus";
import {ResetPassword} from "@/api/user";
import router from "@/router";
import {GetCode} from "@/api/mail";
export default {
name: "ForgetPassword",
data() {
return {
ruleForm: {
loading: false,
username: '',
password: '',
checkPassword: '',
code: '',
},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'blur'},
{min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 5, max: 11, message: '长度在 5 到 11 个字符', trigger: 'blur'}
],
code: [
{required: true, message: '请输入验证码', trigger: 'blur'},
],
}
}
},
methods: {
getCode(){
this.$refs["ruleForm"].validateField('username',valid=>{
if(valid){
GetCode(this.ruleForm.username).then(res=>{
if(res.code===200){
this.$message({
type:'success',
message:'验证码已发送'
})
}
})
}
})
},
resetPassword() {
this.$refs['ruleForm'].validate(valid=>{
if(valid){
if (this.ruleForm.password !== this.ruleForm.checkPassword) {
return ElMessage('您两次输入的密码不同')
}
const data = {
username: this.ruleForm.username,
password: this.ruleForm.password,
code:this.ruleForm.code
};
this.ruleForm.loading = true
ResetPassword(data).then(res => {
console.log(res)
if (res.code === 200) {
this.ruleForm.loading = false;
router.push("/userLogin")
this.$message({
type:'success',
message:'重置成功'
})
} else {
setTimeout(() => {
this.ruleForm.loading = false;
this.$message({
type:'error',
message:'重置失败'
})
}, 1000)
}
}, () => this.ruleForm.loading = false)
}
})
}
}
}
</script>
<style scoped>
.login_title {
margin: 0 auto 40px auto;
text-align: center;
color: #505458;
}
.login-form-footer {
font-weight: bolder;
color: #91949c;
text-align: center;
}
.login-container {
border-radius: 15px;
background-clip: padding-box;
margin: 70px auto;
width: 450px;
height: 400px;
background: #fff;
padding: 15px 15px 15px 15px;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
text-align: center;
}
body {
margin: 0;
}
.login_title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
el-checkbox {
color: #91949c;
font-weight: bolder;
font-size: 15px;
}
</style>
js文件封装方法:
export function GetCode(username){
return service({
url: '/mail'+'/'+username,
method: 'get',
})
}
export function ResetPassword(data){
return service({
url:'/user/forget',
method:'post',
data:data
})
}
四、后端代码
1、MailService
public interface MailService {
void getCode(String username) throws Exception;
}
2、MailServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lxj.siweiboot.mapper.UserMapper;
import com.lxj.siweiboot.model.entity.User;
import com.lxj.siweiboot.service.MailService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* 用户邮件相关
*/
@Service
public class MailServiceImpl implements MailService {
private final String MAIL = "MAIL" ;
private int timeout = 5;
@Resource
private UserMapper userMapper;
@Resource
private RedisTemplate redisTemplate;
@Resource
private JavaMailSender javaMailSender;
@Override
public void getCode(String username) throws Exception {
//验证用户名与邮件是否匹配
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("username",username);
User u = userMapper.selectOne(queryWrapper);
if(u == null){
throw new Exception("用户名不存在");
}
String mail = u.getEmail();
String verifyCode = String.valueOf(new Random().nextInt(9999));
redisTemplate.opsForValue().set(MAIL+username,verifyCode,timeout, TimeUnit.MINUTES);
// 编写邮箱内容
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<html><head><title></title></head><body>");
stringBuilder.append(" 您好<br/>");
stringBuilder.append(" 您的验证码是:").append(verifyCode).append("<br/>");
stringBuilder.append(" 您可以复制此验证码并返回系统找回密码页面,以验证您的邮箱。<br/>");
stringBuilder.append(" 此验证码只能使用一次,在");
stringBuilder.append(timeout);
stringBuilder.append(" 分钟内有效。验证成功则自动失效。<br/>");
stringBuilder.append(" 如果您没有进行上述操作,请忽略此邮件。");
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
// 发件配置并发送邮件
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
//这里只是设置username 并没有设置host和password,因为host和password在springboot启动创建JavaMailSender实例的时候已经读取了
mimeMessageHelper.setFrom("XXXXXXXXX@163.com");
mimeMessageHelper.setTo(mail);
mimeMessage.setSubject("邮箱验证-重置密码");
mimeMessageHelper.setText(stringBuilder.toString(), true);
javaMailSender.send(mimeMessage);
System.out.println("email");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
3、MailController
import com.lxj.siweiboot.service.MailService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@CrossOrigin("*")
@RestController
@RequestMapping("/api/mail")
public class MailController {
@Resource
private MailService mailService;
@GetMapping("/{username}")
public void getCode(@PathVariable String username) throws Exception {
mailService.getCode(username);
}
}
4、UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Resource
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Resource
RedisTemplate redisTemplate;
@Override
public void resetPassword(ResetPwDto dto) throws Exception {
String username = dto.getUsername();
String code = dto.getCode();
String redisCode = (String) redisTemplate.opsForValue().get("MAIL"+username);
System.out.println("redisCode"+redisCode);
if(redisCode==null|| !redisCode.equals(code)) throw new Exception("验证码错误");
String password = dto.getPassword();
QueryWrapper<User> queryWrapper =new QueryWrapper<>();
queryWrapper.in("username",username);
User u = userMapper.selectOne(queryWrapper);
u.setPassword(bCryptPasswordEncoder.encode(password));
userMapper.updateById(u);
}
}
5、UserController
@CrossOrigin("*")
@RestController
@RequestMapping("/api/user")
public class UserController {
@Resource
private UserService userService;
@PostMapping("/forget")
public void resetPassword(@RequestBody ResetPwDto dto) throws Exception {
userService.resetPassword(dto);
}
}