基于SpringBoot实现邮箱找回密码的代码示例

 更新时间:2024年02月23日 10:50:44   作者:七维大脑  
本文主要介绍了如何基于SpringBoot实现邮箱找回密码,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

1. 实现思路

  1. 用户点击忘记密码
  2. 用户输入用户名以及邮箱,点击获取验证码
  3. 后端校验用户名以及邮箱,正确后生成验证码
  4. 生成的验证码作为value,前缀加用户名为key,放入redis中并设置过期时间
  5. 用户输入验证码以及新的密码点击保存
  6. 后端通过前缀+用户名获取验证码,校验验证码的正确性
  7. 密码修改成功

2. 前端UI页面

图为ProcessOn所画,可作为借鉴。也可设计为先验证用户名然后再进入改密码页面。

3. 发件邮箱要求

作者使用的是163邮箱(其他邮箱也基本一致),需要设置POP3/SMTP/IMAP

开启

  • IMAP/SMTP服务
  • POP3/SMTP服务
    开启会让设置授权码,授权码要记牢!后面需要写在配置里

再往下翻有163 SMTP服务器地址 等下需要配置在application.yml中

各家邮箱大同小异,企业邮箱的话应该是可以直接用的,不用开启。

4. 代码实现

4.1 依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

4.2 application.yml配置

# 配置邮箱服务器,账号密码等
spring:
  mail:
    host: smtp.163.com
    username: xxxxxx@163.com
    password: ERBDGXLVJAQMWMDI(授权码)

4.3 获取验证码controller

import com.clisoft.srmsbackend.common.response.ServerResponse;
import com.clisoft.srmsbackend.service.IMailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 邮箱业务 前端控制器
 * @author zzw
 * @date 2022-01-14
 */
@Api(tags = "邮箱业务管理")
@RestController
@RequestMapping("/mail")
public class MailController {

    @Autowired
    private IMailService mailService;

    /**
     * 获取重置密码的验证码
     */
    @ApiOperation(value = "获取重置密码的验证码", notes = "获取重置密码的验证码", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "staffNumber", value = "用户编号(账号)", required = true, paramType = "form"),
            @ApiImplicitParam(name = "mailAddress", value = "邮箱地址", required = true, paramType = "form"),
    })
    @GetMapping("/getCode")
    public ServerResponse getCode(String staffNumber,String mailAddress){
        return mailService.getCode(staffNumber,mailAddress);
    }
}

4.4 ServiceImpl层

import com.clisoft.srmsbackend.common.constant.Constants;
import com.clisoft.srmsbackend.common.response.ServerResponse;
import com.clisoft.srmsbackend.config.MailCodeConfig;
import com.clisoft.srmsbackend.dao.entity.PersStaff;
import com.clisoft.srmsbackend.dao.mapper.PersStaffMapper;
import com.clisoft.srmsbackend.framework.redis.RedisCache;
import com.clisoft.srmsbackend.service.IMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 邮箱业务 实现类
 *
 * @author zzw
 * @date 2022-01-14
 */
@Service
public class MailServiceImpl implements IMailService {

    @Autowired
    private PersStaffMapper persStaffMapper;

    @Autowired
    private MailCodeConfig mailCodeConfig;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String mailUserName;

    /**
     * 获取重置密码的验证码
     *
     * @param staffNumber 用户账号
     * @param mailAddress 用户邮箱
     * @return
     */
    @Override
    public ServerResponse getCode(String staffNumber, String mailAddress) {
        // 非空校验
        if (null == staffNumber || "".equals(staffNumber)) return ServerResponse.createByErrorMessage("账号不能为空!");
        if (null == mailAddress || "".equals(mailAddress)) return ServerResponse.createByErrorMessage("邮箱不能为空!");

        // 账号存在校验
        PersStaff persStaff = persStaffMapper.selectPersStaffByStaffNumber(staffNumber);
        if (null == persStaff) return ServerResponse.createBySuccessMessage("账号不存在!");
        if (!persStaff.getEmail().equals(mailAddress)) return ServerResponse.createByErrorMessage("输入邮箱和预留邮箱不一致!");

        String verifyCode = redisCache.getCacheObject(Constants.MAIL_CODE_KEY + staffNumber);
        if (verifyCode == null) {
            verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);//生成短信验证码
        }
        Integer overtime = mailCodeConfig.getOvertime(); // 过期时间
        // 验证码存入redis并设置过期时间
        redisCache.setCacheObject(Constants.MAIL_CODE_KEY + staffNumber, verifyCode, overtime, 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(overtime.toString());
        stringBuilder.append("分钟内有效。验证成功则自动失效。<br/>");
        stringBuilder.append("如果您没有进行上述操作,请忽略此邮件。");
        MimeMessage mimeMessage = mailSender.createMimeMessage();

        // 发件配置并发送邮件
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //这里只是设置username 并没有设置host和password,因为host和password在springboot启动创建JavaMailSender实例的时候已经读取了
            mimeMessageHelper.setFrom(mailUserName);
            // 用户的邮箱地址
            mimeMessageHelper.setTo(mailAddress);
            // 邮件的标题
            mimeMessage.setSubject("邮箱验证-科研管理系统");
            // 上面所拼接的邮件内容
            mimeMessageHelper.setText(stringBuilder.toString(), true);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return ServerResponse.createBySuccessMessage("获取验证码成功,请查看移步您的邮箱" + mailAddress + "查看验证码!");
    }
}

4.5 修改密码controller

/**
     * 验证码重置密码
     */
    @ApiOperation(value = "验证码重置密码", notes = "验证码重置密码", httpMethod = "POST")
    @PostMapping("/codeUpdatePwd")
    public ServerResponse codeUpdatePwd(@RequestBody CodeUpdatePwdVo codeUpdatePwdVo){
        return persStaffService.codeUpdatePwd(codeUpdatePwdVo);
    }

4.6 修改密码ServiceImpl

 /**
     * 验证码重置密码
     *
     * @param codeUpdatePwdVo
     * @return
     */
    @Override
    public ServerResponse codeUpdatePwd(CodeUpdatePwdVo codeUpdatePwdVo) {
        String staffNumber = codeUpdatePwdVo.getStaffNumber();
        String code = codeUpdatePwdVo.getCode();
        String loginPassword = codeUpdatePwdVo.getLoginPassword();
        // 非空校验
        if (null == staffNumber || "".equals(staffNumber)) return ServerResponse.createByErrorMessage("账号不能为空!");
        if (null == code || "".equals(code)) return ServerResponse.createByErrorMessage("验证码不能为空!");
        if (null == loginPassword || "".equals(loginPassword)) return ServerResponse.createByErrorMessage("密码不能为空!");

        // 账号存在校验
        PersStaff persStaff = persStaffMapper.selectPersStaffByStaffNumber(staffNumber);
        if (null == persStaff) return ServerResponse.createBySuccessMessage("账号不存在!");

        // 验证码过期校验
        String cacheCode = redisCache.getCacheObject(Constants.MAIL_CODE_KEY + staffNumber); // 获取缓存中该账号的验证码
        if (cacheCode == null) {
            return ServerResponse.createByErrorMessage("验证码已过期,请重新获取!");
        }

        // 验证码正确性校验
        if (!cacheCode.equals(code)) {
            return ServerResponse.createByErrorMessage("验证码错误!");
        }

        // 修改密码
        int result = 0;
        try {
            result = persStaffMapper.updatePwdByStaffNumber(staffNumber, PasswordStorageUtil.createHash(codeUpdatePwdVo.getLoginPassword()));
        } catch (PasswordStorageUtil.CannotPerformOperationException e) {
            return ServerResponse.createByErrorMessage("密码加密时发生错误");
        }
        if (result > 0) {
            // 将验证码过期
            redisCache.expire(Constants.MAIL_CODE_KEY + staffNumber, 0);
            return ServerResponse.createBySuccessMessage("密码充值成功!请牢记您的密码!");
        }

        return ServerResponse.createByErrorMessage("未知错误,密码修改失败,请重试!");
    }

4.7 效果图

demo地址:https://gitee.com/lm_8692769/email-reset-password-demo

以上就是基于SpringBoot实现邮箱找回密码的代码示例的详细内容,更多关于SpringBoot实现邮箱找回密码的资料请关注脚本之家其它相关文章!

相关文章

  • Java Map 在put值时value值不被覆盖的解决办法

    Java Map 在put值时value值不被覆盖的解决办法

    这篇文章主要介绍了Java Map 在put值时value值不被覆盖的解决办法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-04-04
  • JAVA发送http get/post请求,调用http接口、方法详解

    JAVA发送http get/post请求,调用http接口、方法详解

    这篇文章主要介绍了Java发送http get/post请求调用接口/方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java Spring MVC 上传下载文件配置及controller方法详解

    Java Spring MVC 上传下载文件配置及controller方法详解

    这篇文章主要介绍了Java Spring MVC 上传下载文件配置及controller方法详解,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • java中Unsafe的使用讲解

    java中Unsafe的使用讲解

    这篇文章主要介绍了java中Unsafe的使用讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 浅谈Java中的四种引用方式的区别

    浅谈Java中的四种引用方式的区别

    下面小编就为大家带来一篇浅谈Java中的四种引用方式的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • 浅谈Java抽象类和接口的个人理解

    浅谈Java抽象类和接口的个人理解

    这篇文章主要介绍了浅谈Java抽象类和接口的个人理解,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Spring boot外部配置(配置中心化)详解

    Spring boot外部配置(配置中心化)详解

    这篇文章主要给大家介绍了关于Spring boot外部配置(配置中心化)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • 分布式医疗挂号系统SpringCache与Redis为数据字典添加缓存

    分布式医疗挂号系统SpringCache与Redis为数据字典添加缓存

    这篇文章主要为大家介绍了分布式医疗挂号系统SpringCache与Redis为数据字典添加缓存,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • java设计模式-代理模式(实例讲解)

    java设计模式-代理模式(实例讲解)

    下面小编就为大家带来一篇java设计模式-代理模式(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • SpringBoot 使用 Maven 打包方式

    SpringBoot 使用 Maven 打包方式

    maven打包有三种方式 pom、jar、war,本篇文章给大家介绍SpringBoot 使用 Maven 打包方式,结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2023-10-10

最新评论