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。

推薦閱讀: