经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
java springboot邮箱找回密码功能的实现讲解
来源:jb51  时间:2022/1/19 11:43:49  对本文有异议

一、主要内容

基于springboot实现密码找回功能。

二、邮箱找回密码的思想

1.输入注册邮箱,点击获取验证码。会将验证码发送到邮箱。

2.用户进入邮箱,查看验证码。

3.用户输入验证码,输入新密码,点击修改密码,完成修改。

三、前台页面

四、注意事项

如果是163或者qq邮箱需要打开授权,以163为例:

如果是阿里的企业邮箱,则不用打开

五、部分实现代码

pom.xml 添加依赖

  1. <dependency>
  2. ?? ?<groupId>org.springframework.boot</groupId>
  3. ?? ?<artifactId>spring-boot-starter-mail</artifactId>
  4. </dependency>

application.properties 配置文件

  1. #这里使用的是阿里企业邮箱
  2. spring.mail.host=smtp.qiye.aliyun.com
  3. spring.mail.username=****@XXXX.com
  4. spring.mail.password=123456

5.1 页面代码

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
  5. <meta http-equiv="expires" content="0">
  6. <meta http-equiv="pragma" content="no-cache">
  7. <meta http-equiv="cache-control" content="no-cache">
  8. <meta charset="UTF-8" />
  9. <title>重置密码</title>
  10. </head>
  11. <body>
  12. <div class="login-bg"></div>
  13. <div class="login-box-reset-pss">
  14. <div class="logbox-left-pss fl">
  15. <div class="logbox-logos-pss">
  16. <img class="sch-logo" src="/images/login_logo.png" alt="" onerror="javascript:this.src='/images/login_logo.png'" />
  17. </div>
  18. </div>
  19. <div class="logbox-right fr">
  20. <div class="title">重置密码</div>
  21. <div class="inputbar">
  22. <input type="text" class="form-control-reset-pss" id="loginNameReset" placeholder="邮箱">
  23. </div>
  24. <div class="inputbar">
  25. <input type="text" class="form-control-reset-pss" id="verificationCode" placeholder="验证码">
  26. <span class="js-reset-captcha btn-captcha" id="btn-captcha">获取验证码</span>
  27. </div>
  28. <div class="inputbar">
  29. <input type="password" class="form-control-reset-pss" id="newLoginPwd" placeholder="新密码">
  30. </div>
  31. <div class="inputbar">
  32. <input type="password" class="form-control-reset-pss" id="confirmloginPwd" placeholder="确认新密码">
  33. </div>
  34. <div class="logbtn"><button type="button" class="fl btn" id="loginIdReset" style="width:100%;height:100%;">保存</button></div>
  35. <div class="logbox-error" style="display:;">您输入的用户名或密码有误,请重新输入!</div>
  36. </div>
  37. </div>
  38. </body>

5.2 发送验证码到注册邮箱的代码

前台代码:

  1. /**
  2. * 获取验证码
  3. */
  4. $el_btnVc.on('click', function(){
  5. var data = {
  6. loginNameReset: $.trim($el_loginReset.val())
  7. }
  8. if(MC.isEmpty(data.loginNameReset)){
  9. return msg_fn('请输入您的用户名!');
  10. }
  11. if (data.loginNameReset.indexOf('.com') > 0 || data.loginNameReset.indexOf('.cn') > 0){
  12. if (!reg_mail.test(data.loginNameReset)){
  13. return msg_fn('请您输入正确的邮箱!');
  14. }
  15. data.resetType = '1';
  16. } else {
  17. if (data.loginNameReset.length != 11){
  18. return msg_fn('请您输入正确的手机号!');
  19. }
  20. data.resetType = '0';
  21. }
  22. // verificationMailOrPhone(data);
  23. reset_getCode(data);
  24. });
  25. /**
  26. * 获取重置密码的验证码
  27. * @param data
  28. */
  29. var reset_getCode = function(data){
  30. $.ajax({
  31. url: window.mcConfig.DATA_HOST,
  32. type: 'post',
  33. dataType: 'json',
  34. // async: false,
  35. data: {
  36. eventType: "web.teacher.user.resetPassword.code",
  37. entity: MC.json.encode(data)
  38. },
  39. success: function(rsp) {
  40. if (parseInt(rsp.err) == 0) {
  41. // window.location.href = data.callback + rsp.code;
  42. MC.msg('info', '验证码已经发送成功!');
  43. } else {
  44. msg_fn(rsp.errMsg || '您输入的用户名或密码有误,请重新输入!');
  45. }
  46. },
  47. error: function(response) {
  48. if (!response.error) {
  49. MC.msg('alert', "系统后台异常,请与管理员联系!", 'warn');
  50. }
  51. }
  52. });
  53. };

后台代码:

controller层

  1. /**
  2. * 获取重置密码的验证码
  3. * @param entity
  4. * @param request
  5. * @param response
  6. * @return
  7. */
  8. @RequestMapping(value = "/getCode", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
  9. public Map<String, Object> getCode(String entity, HttpServletRequest request, HttpServletResponse response) throws MessagingException {
  10. return userService.getCode(JsonUtil.jsonToMap(entity)).toMap(setting);
  11. }

service层:

  1. @Autowired
  2. private JavaMailSender mailSender;
  3. @Value("${spring.mail.username}")
  4. private String mailUserName;
  5. /**
  6. * 获取重置密码需要的验证码
  7. * @param map
  8. * @return
  9. */
  10. public ProcResult getCode(Map<String, Object> map) throws MessagingException {
  11. String loginNameReset = StringUtil.toString(map.get("loginNameReset")).trim();
  12. if (StringUtil.isEmpty(loginNameReset)){
  13. return ProcResult.error(ErrorCode.USER_LOGIN_NAME_EMPTY);
  14. }
  15. List<Teacher> list = getTeacherByMailOrPhoneNumber(loginNameReset,map.get("resetType").toString());
  16. if (list == null || list.size() == 0) {
  17. return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR);
  18. }
  19. if (list.size() > 1) {
  20. return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR);
  21. }
  22. Teacher teacher = list.get(0);
  23. String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);//生成短信验证码
  24. Timestamp outDate = new Timestamp(System.currentTimeMillis() + 5 * 60 * 1000);// 5分钟后过期
  25. //将验证码 和 过期时间更新到数据库
  26. teacher.setCodeExpiredTime(outDate);
  27. teacher.setValidataCode(verifyCode);
  28. teacherDao.update(teacher);
  29. StringBuilder stringBuilder = new StringBuilder();
  30. stringBuilder.append("<html><head><title></title></head><body>");
  31. stringBuilder.append("您好<br/>");
  32. stringBuilder.append("您的验证码是:").append(verifyCode).append("<br/>");
  33. stringBuilder.append("您可以复制此验证码并返回至XXX,以验证您的邮箱。<br/>");
  34. stringBuilder.append("此验证码只能使用一次,在5分钟内有效。验证成功则自动失效。<br/>");
  35. stringBuilder.append("如果您没有进行上述操作,请忽略此邮件。");
  36. MimeMessage mimeMessage = mailSender.createMimeMessage();
  37. //发送验证码到手机或者是邮箱
  38. if ("1".equals(map.get("resetType"))){ //邮箱
  39. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,true);
  40. mimeMessageHelper.setFrom(mailUserName);//这里只是设置username 并没有设置host和password,因为host和password在springboot启动创建JavaMailSender实例的时候已经读取了
  41. mimeMessageHelper.setTo(loginNameReset);
  42. mimeMessage.setSubject("邮箱验证-XXX");
  43. mimeMessageHelper.setText(stringBuilder.toString(),true);
  44. mailSender.send(mimeMessage);
  45. }else if ("0".equals(map.get("resetType"))){ //手机
  46. }
  47. return ProcResult.success();
  48. }

邮箱截图:

5.3 修改密码

前台代码:

  1. /**
  2. * lpw
  3. * 重置密码登录操作
  4. */
  5. $el_btnRt.on('click', function(){
  6. var reg_mail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;//邮箱格式是否正确
  7. var data = {
  8. loginNameReset: $.trim($el_loginReset.val()),
  9. newPassword : $.trim($el_npwd.val()),
  10. confirmNewPassword : $.trim($el_cnpwd.val()),
  11. verificationCode : $.trim($el_vc.val())
  12. }
  13. if(MC.isEmpty(data.loginNameReset)){
  14. return msg_fn('请输入您的用户名!');
  15. }
  16. if(MC.isEmpty(data.verificationCode)){
  17. return msg_fn('请输入验证码!');
  18. }
  19. if (data.loginNameReset.indexOf('.com') > 0 || data.loginNameReset.indexOf('.cn') > 0){
  20. if (!reg_mail.test(data.loginNameReset)){
  21. return msg_fn('请您输入正确的邮箱!');
  22. }
  23. data.resetType = '1';
  24. } else {
  25. if (data.loginNameReset.length != 11){
  26. return msg_fn('请您输入正确的手机号!');
  27. }
  28. data.resetType = '0';
  29. }
  30. if(MC.isEmpty(data.newPassword)){
  31. return msg_fn('请输入您的新密码!');
  32. }
  33. if(MC.isEmpty(data.confirmNewPassword)){
  34. return msg_fn('请确认您的新密码!');
  35. }
  36. if(data.confirmNewPassword != data.newPassword){
  37. return msg_fn('两次输入的密码不一致!');
  38. }
  39. MC.require('md5', function(exports){
  40. data.newPassword = hex_md5(data.newPassword);
  41. data.confirmNewPassword = hex_md5(data.confirmNewPassword);
  42. reset_PassWord(data);
  43. });
  44. });
  45. /**
  46. * 修改密码
  47. * @param data
  48. */
  49. var reset_PassWord = function(data){
  50. $.ajax({
  51. url: window.mcConfig.DATA_HOST,
  52. type: 'post',
  53. dataType: 'json',
  54. // async: false,
  55. data: {
  56. eventType: "web.teacher.user.resetPassword.resetPassword",
  57. entity: MC.json.encode(data)
  58. },
  59. success: function(rsp) {
  60. if (parseInt(rsp.err) == 0) {
  61. MC.msg('info', '密码修改成功,请重新登录!');
  62. } else {
  63. msg_fn(rsp.errMsg || '您输入的用户名或验证码有误,请重新输入!');
  64. }
  65. },
  66. error: function(response) {
  67. if (!response.error) {
  68. MC.msg('alert', "系统后台异常,请与管理员联系!", 'warn');
  69. }
  70. }
  71. });
  72. };

controller层:

  1. /**
  2. * 修改密码
  3. * @param entity
  4. * @param request
  5. * @param response
  6. * @return
  7. */
  8. @RequestMapping(value = "/resetPassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
  9. public Map<String, Object> resetPassword(String entity, HttpServletRequest request, HttpServletResponse response) {
  10. return userService.resetPassword(JsonUtil.jsonToMap(entity)).toMap(setting);
  11. }

service层:

  1. /**
  2. * 重新设置密码
  3. * @param map
  4. * @return
  5. */
  6. public ProcResult resetPassword(Map<String, Object> map) {
  7. String loginNameReset = StringUtil.toString(map.get("loginNameReset")).trim();
  8. if (StringUtil.isEmpty(loginNameReset)){
  9. return ProcResult.error(ErrorCode.USER_LOGIN_NAME_EMPTY);
  10. }
  11. String newPassword = StringUtil.toString(map.get("newPassword")).trim();
  12. if (StringUtils.isEmpty(newPassword)) {
  13. return ProcResult.error(ErrorCode.USER_PASSWORD_EMPTY);
  14. }
  15. String verificationCode = StringUtil.toString(map.get("verificationCode")).trim();
  16. if (StringUtils.isEmpty(verificationCode)) {
  17. return ProcResult.error(ErrorCode.VERIFICATION_CODE_EMPTY);
  18. }
  19. List<Teacher> list = getTeacherByMailOrPhoneNumber(loginNameReset,map.get("resetType").toString());
  20. if (list == null || list.size() == 0) {
  21. return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR);
  22. }
  23. if (list.size() > 1) {
  24. return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR);
  25. }
  26. Teacher teacher = list.get(0);
  27. if (teacher.getValidataCode() == null || "".equals(teacher.getValidataCode())){
  28. return ProcResult.error(ErrorCode.VERIFICATION_CODE_EMPTY);
  29. }
  30. //判断验证码是否还有效
  31. Date codeExpiredTime = teacher.getCodeExpiredTime();
  32. Date date = new Date();
  33. if (date.getTime() > codeExpiredTime.getTime() || "0".equals(teacher.getValidataCode())){
  34. return ProcResult.error(ErrorCode.VERIFICATION_CODE_INVALID);
  35. }
  36. //判断验证码是否正确
  37. if (!verificationCode.equals(teacher.getValidataCode())){
  38. return ProcResult.error(ErrorCode.VERIFICATION_CODE_ERROR);
  39. }
  40. //通过用户no查询user信息
  41. QueryConds queryConds = new QueryConds();
  42. queryConds.cond("userNo", teacher.getUserNo(), QueryOp.EQUAL);
  43. queryConds.cond("del", ECommon.NO_DEL);
  44. List<User> listUser = userDao.findUserByConds(queryConds);
  45. if (listUser == null || listUser.size() == 0) {
  46. return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR);
  47. }
  48. if (listUser.size() > 1) {
  49. return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR);
  50. }
  51. User user = listUser.get(0);
  52. //修改密码
  53. user.setPassword(newPassword);
  54. user.setUpdateTime(date);
  55. userDao.update(user);
  56. //失效当前验证码
  57. teacher.setValidataCode("0");
  58. teacher.setUpdateTime(date);
  59. teacherDao.update(teacher);
  60. return ProcResult.success();
  61. }

OK,至此,邮箱修改密码功能就完成了。

总结

在不使用spring-boot-starter-mail发送邮件的时候,需要在代码中设置host和password

spring-boot-starter-mail只需要在配置文件中配置,在启动springboot的会去配置文件读取host和password属性。不需要再代码中显性设置。如果不配置springboot启动会报错:

  1. #这里使用的是阿里企业邮箱
  2. spring.mail.host=smtp.qiye.aliyun.com
  3. spring.mail.username=****@XXXX.com
  4. spring.mail.password=123456

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号