Springboot+Vue email to retrieve password

1. Preliminary preparation:

1. Download and install redis

Here I attach the redis version I use myself. If you use other versions, you can find resources by yourself. The Baidu network disk link: https://pan.baidu.com/s/1WPAksWV-Vi8vDZz_i2YI5w
Extraction code: ovxd

First unzip to a file, then double-click redies-server.exe to run redis.

2. Add dependencies

<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. Prepare an email.

1. I use 163, find the settings, and click POP3 here.

2. Enable these two services, remember the pop-up series of uppercase letters, which will be configured later.

There is also a server address in the pull-down, which is assigned to host when configuring

2. Backend configuration

Configure in application.properties

# Configure email server, account password, etc.
spring.mail.host=smtp.163.com

[email protected]
spring.mail.password= XXXXXXXXXXXX (authorization code)

The default configuration used by redis, there is no additional configuration.

If your configuration file is application.yml, then use the following code configuration

# Configure email server, account password, etc.
spring:
  mail:
    host: smtp.163.com
    username: [email protected]
    password: XXXXXXXXXXXX (authorization code)

3. Front-end code

Click Forgot Password to jump to the Forgot Password page. Forgot password page and code are as follows:

<template>
  <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="auto" class="login-container"
           :hide-required-asterisk="true">
    <h3 class="login_title">Reset Password</h3>
    <el-form-item label="username:" prop="username">
      <el-input v-model="ruleForm.username"></el-input>
    </el-form-item>
    <el-form-item label="Verification code:" 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">Get Verification Code
      </el-button></el-col>
      </el-row>
    </el-form-item>
    <el-form-item label="Password:" prop="password">
      <el-input type="password" v-model="ruleForm.password" autocomplete="off" show-password></el-input>
    </el-form-item>
    <el-form-item label="Confirm Password:" 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">Reset password
      </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: 'Please enter the user name', trigger: 'blur'},
          {min: 1, max: 10, message: 'length between 1 and 10 characters', trigger: 'blur'}
        ],
        password: [
          {required: true, message: 'Please enter the password', trigger: 'blur'},
          {min: 5, max: 11, message: 'length between 5 and 11 characters', trigger: 'blur'}
        ],
        code: [
          {required: true, message: 'Please enter the verification code', 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:'Verification code has been sent'
              })
            }
          })
        }
      })
    },
    resetPassword() {
      this.$refs['ruleForm'].validate(valid=>{
        if(valid){
          if (this.ruleForm.password !== this.ruleForm.checkPassword) {
            return ElMessage('The password you entered twice is different')
          }

          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:'reset successful'
                })
            } else {
              setTimeout(() => {
                this.ruleForm.loading = false;
                this. $message({
                  type:'error',
                  message:'Reset failed'
                })
              }, 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 file encapsulation method:

export function GetCode(username){
    return service({
        url: '/mail' + '/' + username,
        method: 'get',
    })
}

export function ResetPassword(data){
    return service({
        url:'/user/forget',
        method:'post',
        data: data
    })
}

4. Backend code

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;

/**
 * User email related
 */
@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 {
        //Verify that the username matches the email
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("username",username);
        User u = userMapper. selectOne(queryWrapper);
        if(u == null){
            throw new Exception("Username does not exist");
        }
        String mail = u. getEmail();
        String verifyCode = String. valueOf(new Random(). nextInt(9999));
        redisTemplate.opsForValue().set(MAIL + username, verifyCode, timeout, TimeUnit.MINUTES);

        // write email content
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<html><head><title></title></head><body>");
        stringBuilder.append("Hello<br/>");
        stringBuilder.append("Your verification code is:").append(verifyCode).append("<br/>");
        stringBuilder.append("You can copy this verification code and return to the system reset password page to verify your email.<br/>");
        stringBuilder.append(" This verification code can only be used once, in");
        stringBuilder.append(timeout);
        stringBuilder.append(" Valid within minutes. If the verification is successful, it will automatically become invalid.<br/>");
        stringBuilder.append("If you did not do the above, please ignore this email.");
        MimeMessage mimeMessage = javaMailSender. createMimeMessage();

        // Send mail configuration and send mail
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //This is just setting the username and not setting the host and password, because the host and password have been read when springboot starts to create a JavaMailSender instance
            mimeMessageHelper.setFrom("[email protected]");
            mimeMessageHelper.setTo(mail);
            mimeMessage.setSubject("Mailbox verification-reset password");
            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("Verification code error");
        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);
    }
}

Above, part of the reference is based on SpringBoot to retrieve the password by email