一、主要内容
基于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

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