java springboot郵箱找回密碼功能的實現講解
一、主要內容
基於springboot實現密碼找回功能。
二、郵箱找回密碼的思想
1.輸入註冊郵箱,點擊獲取驗證碼。會將驗證碼發送到郵箱。
2.用戶進入郵箱,查看驗證碼。
3.用戶輸入驗證碼,輸入新密碼,點擊修改密碼,完成修改。
三、前臺頁面
四、註意事項
如果是163或者qq郵箱需要打開授權,以163為例:
如果是阿裡的企業郵箱,則不用打開
五、部分實現代碼
pom.xml 添加依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
application.properties 配置文件
#這裡使用的是阿裡企業郵箱 spring.mail.host=smtp.qiye.aliyun.com spring.mail.username=****@XXXX.com spring.mail.password=123456
5.1 頁面代碼
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="expires" content="0"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta charset="UTF-8" /> <title>重置密碼</title> </head> <body> <div class="login-bg"></div> <div class="login-box-reset-pss"> <div class="logbox-left-pss fl"> <div class="logbox-logos-pss"> <img class="sch-logo" src="/images/login_logo.png" alt="" onerror="javascript:this.src='/images/login_logo.png'" /> </div> </div> <div class="logbox-right fr"> <div class="title">重置密碼</div> <div class="inputbar"> <input type="text" class="form-control-reset-pss" id="loginNameReset" placeholder="郵箱"> </div> <div class="inputbar"> <input type="text" class="form-control-reset-pss" id="verificationCode" placeholder="驗證碼"> <span class="js-reset-captcha btn-captcha" id="btn-captcha">獲取驗證碼</span> </div> <div class="inputbar"> <input type="password" class="form-control-reset-pss" id="newLoginPwd" placeholder="新密碼"> </div> <div class="inputbar"> <input type="password" class="form-control-reset-pss" id="confirmloginPwd" placeholder="確認新密碼"> </div> <div class="logbtn"><button type="button" class="fl btn" id="loginIdReset" style="width:100%;height:100%;">保存</button></div> <div class="logbox-error" style="display:;">您輸入的用戶名或密碼有誤,請重新輸入!</div> </div> </div> </body>
5.2 發送驗證碼到註冊郵箱的代碼
前臺代碼:
/** * 獲取驗證碼 */ $el_btnVc.on('click', function(){ var data = { loginNameReset: $.trim($el_loginReset.val()) } if(MC.isEmpty(data.loginNameReset)){ return msg_fn('請輸入您的用戶名!'); } if (data.loginNameReset.indexOf('.com') > 0 || data.loginNameReset.indexOf('.cn') > 0){ if (!reg_mail.test(data.loginNameReset)){ return msg_fn('請您輸入正確的郵箱!'); } data.resetType = '1'; } else { if (data.loginNameReset.length != 11){ return msg_fn('請您輸入正確的手機號!'); } data.resetType = '0'; } // verificationMailOrPhone(data); reset_getCode(data); }); /** * 獲取重置密碼的驗證碼 * @param data */ var reset_getCode = function(data){ $.ajax({ url: window.mcConfig.DATA_HOST, type: 'post', dataType: 'json', // async: false, data: { eventType: "web.teacher.user.resetPassword.code", entity: MC.json.encode(data) }, success: function(rsp) { if (parseInt(rsp.err) == 0) { // window.location.href = data.callback + rsp.code; MC.msg('info', '驗證碼已經發送成功!'); } else { msg_fn(rsp.errMsg || '您輸入的用戶名或密碼有誤,請重新輸入!'); } }, error: function(response) { if (!response.error) { MC.msg('alert', "系統後臺異常,請與管理員聯系!", 'warn'); } } }); };
後臺代碼:
controller層
/** * 獲取重置密碼的驗證碼 * @param entity * @param request * @param response * @return */ @RequestMapping(value = "/getCode", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public Map<String, Object> getCode(String entity, HttpServletRequest request, HttpServletResponse response) throws MessagingException { return userService.getCode(JsonUtil.jsonToMap(entity)).toMap(setting); }
service層:
@Autowired private JavaMailSender mailSender; @Value("${spring.mail.username}") private String mailUserName; /** * 獲取重置密碼需要的驗證碼 * @param map * @return */ public ProcResult getCode(Map<String, Object> map) throws MessagingException { String loginNameReset = StringUtil.toString(map.get("loginNameReset")).trim(); if (StringUtil.isEmpty(loginNameReset)){ return ProcResult.error(ErrorCode.USER_LOGIN_NAME_EMPTY); } List<Teacher> list = getTeacherByMailOrPhoneNumber(loginNameReset,map.get("resetType").toString()); if (list == null || list.size() == 0) { return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR); } if (list.size() > 1) { return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR); } Teacher teacher = list.get(0); String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);//生成短信驗證碼 Timestamp outDate = new Timestamp(System.currentTimeMillis() + 5 * 60 * 1000);// 5分鐘後過期 //將驗證碼 和 過期時間更新到數據庫 teacher.setCodeExpiredTime(outDate); teacher.setValidataCode(verifyCode); teacherDao.update(teacher); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("<html><head><title></title></head><body>"); stringBuilder.append("您好<br/>"); stringBuilder.append("您的驗證碼是:").append(verifyCode).append("<br/>"); stringBuilder.append("您可以復制此驗證碼並返回至XXX,以驗證您的郵箱。<br/>"); stringBuilder.append("此驗證碼隻能使用一次,在5分鐘內有效。驗證成功則自動失效。<br/>"); stringBuilder.append("如果您沒有進行上述操作,請忽略此郵件。"); MimeMessage mimeMessage = mailSender.createMimeMessage(); //發送驗證碼到手機或者是郵箱 if ("1".equals(map.get("resetType"))){ //郵箱 MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,true); mimeMessageHelper.setFrom(mailUserName);//這裡隻是設置username 並沒有設置host和password,因為host和password在springboot啟動創建JavaMailSender實例的時候已經讀取瞭 mimeMessageHelper.setTo(loginNameReset); mimeMessage.setSubject("郵箱驗證-XXX"); mimeMessageHelper.setText(stringBuilder.toString(),true); mailSender.send(mimeMessage); }else if ("0".equals(map.get("resetType"))){ //手機 } return ProcResult.success(); }
郵箱截圖:
5.3 修改密碼
前臺代碼:
/** * lpw * 重置密碼登錄操作 */ $el_btnRt.on('click', function(){ var reg_mail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;//郵箱格式是否正確 var data = { loginNameReset: $.trim($el_loginReset.val()), newPassword : $.trim($el_npwd.val()), confirmNewPassword : $.trim($el_cnpwd.val()), verificationCode : $.trim($el_vc.val()) } if(MC.isEmpty(data.loginNameReset)){ return msg_fn('請輸入您的用戶名!'); } if(MC.isEmpty(data.verificationCode)){ return msg_fn('請輸入驗證碼!'); } if (data.loginNameReset.indexOf('.com') > 0 || data.loginNameReset.indexOf('.cn') > 0){ if (!reg_mail.test(data.loginNameReset)){ return msg_fn('請您輸入正確的郵箱!'); } data.resetType = '1'; } else { if (data.loginNameReset.length != 11){ return msg_fn('請您輸入正確的手機號!'); } data.resetType = '0'; } if(MC.isEmpty(data.newPassword)){ return msg_fn('請輸入您的新密碼!'); } if(MC.isEmpty(data.confirmNewPassword)){ return msg_fn('請確認您的新密碼!'); } if(data.confirmNewPassword != data.newPassword){ return msg_fn('兩次輸入的密碼不一致!'); } MC.require('md5', function(exports){ data.newPassword = hex_md5(data.newPassword); data.confirmNewPassword = hex_md5(data.confirmNewPassword); reset_PassWord(data); }); }); /** * 修改密碼 * @param data */ var reset_PassWord = function(data){ $.ajax({ url: window.mcConfig.DATA_HOST, type: 'post', dataType: 'json', // async: false, data: { eventType: "web.teacher.user.resetPassword.resetPassword", entity: MC.json.encode(data) }, success: function(rsp) { if (parseInt(rsp.err) == 0) { MC.msg('info', '密碼修改成功,請重新登錄!'); } else { msg_fn(rsp.errMsg || '您輸入的用戶名或驗證碼有誤,請重新輸入!'); } }, error: function(response) { if (!response.error) { MC.msg('alert', "系統後臺異常,請與管理員聯系!", 'warn'); } } }); };
controller層:
/** * 修改密碼 * @param entity * @param request * @param response * @return */ @RequestMapping(value = "/resetPassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public Map<String, Object> resetPassword(String entity, HttpServletRequest request, HttpServletResponse response) { return userService.resetPassword(JsonUtil.jsonToMap(entity)).toMap(setting); }
service層:
/** * 重新設置密碼 * @param map * @return */ public ProcResult resetPassword(Map<String, Object> map) { String loginNameReset = StringUtil.toString(map.get("loginNameReset")).trim(); if (StringUtil.isEmpty(loginNameReset)){ return ProcResult.error(ErrorCode.USER_LOGIN_NAME_EMPTY); } String newPassword = StringUtil.toString(map.get("newPassword")).trim(); if (StringUtils.isEmpty(newPassword)) { return ProcResult.error(ErrorCode.USER_PASSWORD_EMPTY); } String verificationCode = StringUtil.toString(map.get("verificationCode")).trim(); if (StringUtils.isEmpty(verificationCode)) { return ProcResult.error(ErrorCode.VERIFICATION_CODE_EMPTY); } List<Teacher> list = getTeacherByMailOrPhoneNumber(loginNameReset,map.get("resetType").toString()); if (list == null || list.size() == 0) { return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR); } if (list.size() > 1) { return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR); } Teacher teacher = list.get(0); if (teacher.getValidataCode() == null || "".equals(teacher.getValidataCode())){ return ProcResult.error(ErrorCode.VERIFICATION_CODE_EMPTY); } //判斷驗證碼是否還有效 Date codeExpiredTime = teacher.getCodeExpiredTime(); Date date = new Date(); if (date.getTime() > codeExpiredTime.getTime() || "0".equals(teacher.getValidataCode())){ return ProcResult.error(ErrorCode.VERIFICATION_CODE_INVALID); } //判斷驗證碼是否正確 if (!verificationCode.equals(teacher.getValidataCode())){ return ProcResult.error(ErrorCode.VERIFICATION_CODE_ERROR); } //通過用戶no查詢user信息 QueryConds queryConds = new QueryConds(); queryConds.cond("userNo", teacher.getUserNo(), QueryOp.EQUAL); queryConds.cond("del", ECommon.NO_DEL); List<User> listUser = userDao.findUserByConds(queryConds); if (listUser == null || listUser.size() == 0) { return ProcResult.error(ErrorCode.LOGIN_USER_NOT_EXISTS_ERROR); } if (listUser.size() > 1) { return ProcResult.error(ErrorCode.USER_NOT_ONE_ERROR); } User user = listUser.get(0); //修改密碼 user.setPassword(newPassword); user.setUpdateTime(date); userDao.update(user); //失效當前驗證碼 teacher.setValidataCode("0"); teacher.setUpdateTime(date); teacherDao.update(teacher); return ProcResult.success(); }
OK,至此,郵箱修改密碼功能就完成瞭。
總結
在不使用spring-boot-starter-mail發送郵件的時候,需要在代碼中設置host和password
spring-boot-starter-mail隻需要在配置文件中配置,在啟動springboot的會去配置文件讀取host和password屬性。不需要再代碼中顯性設置。如果不配置springboot啟動會報錯:
#這裡使用的是阿裡企業郵箱 spring.mail.host=smtp.qiye.aliyun.com spring.mail.username=****@XXXX.com spring.mail.password=123456
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java畢業設計實戰之校園一卡通系統的實現
- Java 實戰項目之畢業設計管理系統的實現流程
- MybatisPlus修改時空字段無法修改的解決方案
- springboot框架的全局異常處理方案詳解
- java使用枚舉封裝錯誤碼及錯誤信息詳解