1. 实现思路
- 用户点击忘记密码
- 用户输入用户名以及邮箱,点击获取验证码
- 后端校验用户名以及邮箱,正确后生成验证码
- 生成的验证码作为value,前缀加用户名为key,放入redis中并设置过期时间
- 用户输入验证码以及新的密码点击保存
- 后端通过前缀+用户名获取验证码,校验验证码的正确性
- 密码修改成功
2. 前端UI页面
图为ProcessOn所画,可作为借鉴。也可设计为先验证用户名然后再进入改密码页面。
3. 发件邮箱要求
作者使用的是163邮箱(其他邮箱也基本一致),需要设置POP3/SMTP/IMAP
开启
- IMAP/SMTP服务
- POP3/SMTP服务
开启会让设置授权码,授权码要记牢!后面需要写在配置里
再往下翻有163 SMTP服务器地址 等下需要配置在application.yml中
各家邮箱大同小异,企业邮箱的话应该是可以直接用的,不用开启。
4. 代码实现
4.1 依赖
1 | org.springframework.bootspring-boot-starter-mail |
4.2 application.yml配置
1 2 3 4 5 6 | # 配置邮箱服务器,账号密码等 spring: mail: host: smtp.163.com username: xxxxxx@163.com password: ERBDGXLVJAQMWMDI(授权码) |
4.3 获取验证码controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 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( "<title></title>" ); 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
1 2 3 4 5 6 7 8 | /** * 验证码重置密码 */ @ApiOperation (value = "验证码重置密码" , notes = "验证码重置密码" , httpMethod = "POST" ) @PostMapping ( "/codeUpdatePwd" ) public ServerResponse codeUpdatePwd( @RequestBody CodeUpdatePwdVo codeUpdatePwdVo){ return persStaffService.codeUpdatePwd(codeUpdatePwdVo); } |
4.6 修改密码ServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /** * 验证码重置密码 * * @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实现邮箱找回密码的资料请关注IT俱乐部其它相关文章!