From 81793205c162caad091cf3538988cdadc5c37297 Mon Sep 17 00:00:00 2001 From: thinkgem Date: Sun, 8 Jul 2018 22:45:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=BE=E5=9B=9E=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E6=89=8B=E6=9C=BA=E5=8F=B7=E3=80=81=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E3=80=81=E4=BF=9D=E5=AF=86=E9=97=AE=E9=A2=98=E6=89=BE=E5=9B=9E?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jeesite/common/mail/EmailUtils.java | 304 +----------------- .../com/jeesite/common/msg/EmailUtils.java | 80 +++++ .../sys/web/user/AccountController.java | 117 ++++--- .../main/resources/config/jeesite-core.yml | 15 +- .../views/modules/sys/account/forgetPwd.html | 187 +++++++++++ 5 files changed, 355 insertions(+), 348 deletions(-) create mode 100644 common/src/main/java/com/jeesite/common/msg/EmailUtils.java create mode 100644 modules/core/src/main/resources/views/modules/sys/account/forgetPwd.html diff --git a/common/src/main/java/com/jeesite/common/mail/EmailUtils.java b/common/src/main/java/com/jeesite/common/mail/EmailUtils.java index 58307b4f..8454eecd 100644 --- a/common/src/main/java/com/jeesite/common/mail/EmailUtils.java +++ b/common/src/main/java/com/jeesite/common/mail/EmailUtils.java @@ -3,13 +3,10 @@ */ package com.jeesite.common.mail; -import org.apache.commons.mail.HtmlEmail; - -import com.jeesite.common.io.PropertiesUtils; - /** * 发送电子邮件 */ +@Deprecated public class EmailUtils { /** @@ -19,14 +16,9 @@ public class EmailUtils { * @param content 内容 * @return */ + @Deprecated public static boolean sendEmail(String toAddress, String subject, String content) { - PropertiesUtils loader = PropertiesUtils.getInstance(); - String fromAddress = loader.getProperty("msg.email.fromAddress"); - String fromPassword = loader.getProperty("msg.email.fromPassword"); - String fromHostName = loader.getProperty("msg.email.fromHostName"); - String sslOnConnect = loader.getProperty("msg.email.sslOnConnect", "false"); - String sslSmtpPort = loader.getProperty("msg.email.sslSmtpPort"); - return sendEmail(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content); + return com.jeesite.common.msg.EmailUtils.send(toAddress, subject, content); } /** @@ -36,296 +28,10 @@ public class EmailUtils { * @param content 内容 * @return */ + @Deprecated public static boolean sendEmail(String fromAddress, String fromPassword, String fromHostName, String sslOnConnect, String sslSmtpPort, String toAddress, String subject, String content) { - try { - HtmlEmail htmlEmail = new HtmlEmail(); - // 发送地址 - htmlEmail.setFrom(fromAddress); - // 密码校验 - htmlEmail.setAuthentication(fromAddress, fromPassword); - // 发送服务器协议 - htmlEmail.setHostName(fromHostName); - - // SSL - if ("true".equals(sslOnConnect)) { - htmlEmail.setSSLOnConnect(true); - htmlEmail.setSslSmtpPort(sslSmtpPort); - } - - // 接收地址 - htmlEmail.addTo(toAddress); - - // 标题 - htmlEmail.setSubject(subject); - // 内容 - htmlEmail.setMsg(content); - - // 其他信息 - htmlEmail.setCharset("utf-8"); - - // 发送 - htmlEmail.send(); - return true; - } catch (Exception e) { - e.printStackTrace(); - } - return false; - + return com.jeesite.common.msg.EmailUtils.send(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content); } - -// // private static final String smtphost = "192.168.1.70"; -// private static final String from = "thinkgem@163.com"; -// private static final String fromName = "测试公司"; -// private static final String charSet = "utf-8"; -// private static final String username = "thinkgem@163.com"; -// private static final String password = "123456"; -// -// private static Map hostMap = new HashMap(); -// static { -// // 126 -// hostMap.put("smtp.126", "smtp.126.com"); -// // qq -// hostMap.put("smtp.qq", "smtp.qq.com"); -// -// // 163 -// hostMap.put("smtp.163", "smtp.163.com"); -// -// // sina -// hostMap.put("smtp.sina", "smtp.sina.com.cn"); -// -// // tom -// hostMap.put("smtp.tom", "smtp.tom.com"); -// -// // 263 -// hostMap.put("smtp.263", "smtp.263.net"); -// -// // yahoo -// hostMap.put("smtp.yahoo", "smtp.mail.yahoo.com"); -// -// // hotmail -// hostMap.put("smtp.hotmail", "smtp.live.com"); -// -// // gmail -// hostMap.put("smtp.gmail", "smtp.gmail.com"); -// hostMap.put("smtp.port.gmail", "465"); -// } -// -// public static String getHost(String email) throws Exception { -// Pattern pattern = Pattern.compile("\\w+@(\\w+)(\\.\\w+){1,2}"); -// Matcher matcher = pattern.matcher(email); -// String key = "unSupportEmail"; -// if (matcher.find()) { -// key = "smtp." + matcher.group(1); -// } -// if (hostMap.containsKey(key)) { -// return hostMap.get(key); -// } else { -// throw new Exception("unSupportEmail"); -// } -// } -// -// public static int getSmtpPort(String email) throws Exception { -// Pattern pattern = Pattern.compile("\\w+@(\\w+)(\\.\\w+){1,2}"); -// Matcher matcher = pattern.matcher(email); -// String key = "unSupportEmail"; -// if (matcher.find()) { -// key = "smtp.port." + matcher.group(1); -// } -// if (hostMap.containsKey(key)) { -// return Integer.parseInt(hostMap.get(key)); -// } else { -// return 25; -// } -// } -// -// /** -// * 发送模板邮件 -// * -// * @param toMailAddr 收信人地址 -// * @param subject email主题 -// * @param templatePath 模板地址 -// * @param map 模板map -// */ -// public static void sendFtlMail(String toMailAddr, String subject, String templatePath, Map map) { -// Template template = null; -// Configuration freeMarkerConfig = null; -// HtmlEmail hemail = new HtmlEmail(); -// try { -// hemail.setHostName(getHost(from)); -// hemail.setSmtpPort(getSmtpPort(from)); -// hemail.setCharset(charSet); -// hemail.addTo(toMailAddr); -// hemail.setFrom(from, fromName); -// hemail.setAuthentication(username, password); -// hemail.setSubject(subject); -// freeMarkerConfig = new Configuration(); -// freeMarkerConfig.setDirectoryForTemplateLoading(new File(getFilePath())); -// // 获取模板 -// template = freeMarkerConfig.getTemplate(getFileName(templatePath), new Locale("Zh_cn"), "UTF-8"); -// // 模板内容转换为string -// String htmlText = FreeMarkers.renderTemplate(template, map); -// System.out.println(htmlText); -// hemail.setMsg(htmlText); -// hemail.send(); -// System.out.println("email send true!"); -// } catch (Exception e) { -// e.printStackTrace(); -// System.out.println("email send error!"); -// } -// } -// -// /** -// * 发送普通邮件 -// * -// * @param toMailAddr 收信人地址 -// * @param subject email主题 -// * @param message 发送email信息 -// */ -// public static void sendCommonMail(String toMailAddr, String subject, String message) { -// HtmlEmail hemail = new HtmlEmail(); -// try { -// hemail.setHostName(getHost(from)); -// hemail.setSmtpPort(getSmtpPort(from)); -// hemail.setCharset(charSet); -// hemail.addTo(toMailAddr); -// hemail.setFrom(from, fromName); -// hemail.setAuthentication(username, password); -// hemail.setSubject(subject); -// hemail.setMsg(message); -// hemail.send(); -// System.out.println("email send true!"); -// } catch (Exception e) { -// e.printStackTrace(); -// System.out.println("email send error!"); -// } -// -// } -// -// public static String getHtmlText(String templatePath, Map map) { -// Template template = null; -// String htmlText = ""; -// try { -// Configuration freeMarkerConfig = null; -// freeMarkerConfig = new Configuration(); -// freeMarkerConfig.setDirectoryForTemplateLoading(new File(getFilePath())); -// // 获取模板 -// template = freeMarkerConfig.getTemplate(getFileName(templatePath), new Locale("Zh_cn"), "UTF-8"); -// // 模板内容转换为string -// htmlText = FreeMarkers.renderTemplate(template, map); -// System.out.println(htmlText); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return htmlText; -// } -// -// private static String getFilePath() { -// String path = getAppPath(SendMailUtil.class); -// path = path + File.separator + "mailtemplate" + File.separator; -// path = path.replace("\\", "/"); -// System.out.println(path); -// return path; -// } -// -// private static String getFileName(String path) { -// path = path.replace("\\", "/"); -// System.out.println(path); -// return path.substring(path.lastIndexOf("/") + 1); -// } -// -// // @SuppressWarnings("unchecked") -// public static String getAppPath(Class cls) { -// // 检查用户传入的参数是否为空 -// if (cls == null) -// throw new java.lang.IllegalArgumentException("参数不能为空!"); -// ClassLoader loader = cls.getClassLoader(); -// // 获得类的全名,包括包名 -// String clsName = cls.getName() + ".class"; -// // 获得传入参数所在的包 -// Package pack = cls.getPackage(); -// String path = ""; -// // 如果不是匿名包,将包名转化为路径 -// if (pack != null) { -// String packName = pack.getName(); -// // 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库 -// if (packName.startsWith("java.") || packName.startsWith("javax.")) -// throw new java.lang.IllegalArgumentException("不要传送系统类!"); -// // 在类的名称中,去掉包名的部分,获得类的文件名 -// clsName = clsName.substring(packName.length() + 1); -// // 判定包名是否是简单包名,如果是,则直接将包名转换为路径, -// if (packName.indexOf(".") < 0) -// path = packName + "/"; -// else {// 否则按照包名的组成部分,将包名转换为路径 -// int start = 0, end = 0; -// end = packName.indexOf("."); -// while (end != -1) { -// path = path + packName.substring(start, end) + "/"; -// start = end + 1; -// end = packName.indexOf(".", start); -// } -// path = path + packName.substring(start) + "/"; -// } -// } -// // 调用ClassLoader的getResource方法,传入包含路径信息的类文件名 -// java.net.URL url = loader.getResource(path + clsName); -// // 从URL对象中获取路径信息 -// String realPath = url.getPath(); -// // 去掉路径信息中的协议名"file:" -// int pos = realPath.indexOf("file:"); -// if (pos > -1) -// realPath = realPath.substring(pos + 5); -// // 去掉路径信息最后包含类文件信息的部分,得到类所在的路径 -// pos = realPath.indexOf(path + clsName); -// realPath = realPath.substring(0, pos - 1); -// // 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名 -// if (realPath.endsWith("!")) -// realPath = realPath.substring(0, realPath.lastIndexOf("/")); -// /*------------------------------------------------------------ -// ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径 -// 中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要 -// 的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的 -// 中文及空格路径 -// -------------------------------------------------------------*/ -// try { -// realPath = java.net.URLDecoder.decode(realPath, "utf-8"); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// System.out.println("realPath----->" + realPath); -// return realPath; -// } -// -// // private static File getFile(String path){ -// // File file = -// // SendMail.class.getClassLoader().getResource("mailtemplate/test.ftl").getFile(); -// // return file; -// // } -// // -// -// public static void main(String[] args) { -// // HtmlEmail hemail = new HtmlEmail(); -// // try { -// // hemail.setHostName("smtp.exmail.qq.com"); -// // hemail.setCharset("utf-8"); -// // hemail.addTo("test@qq.com"); -// // hemail.setFrom("test@qq.com", "test"); -// // hemail.setAuthentication("test@test.com", "test@aa"); -// // hemail.setSubject("sendemail test!"); -// // hemail.setMsg("谷歌
"); -// // hemail.send(); -// // System.out.println("email send true!"); -// // } catch (Exception e) { -// // e.printStackTrace(); -// // System.out.println("email send error!"); -// // } -// Map map = new HashMap(); -// map.put("subject", "测试标题"); -// map.put("content", "测试 内容"); -// String templatePath = "mailtemplate/test.ftl"; -// sendFtlMail("test@163.com", "sendemail test!", templatePath, map); -// -// // System.out.println(getFileName("mailtemplate/test.ftl")); -// } } \ No newline at end of file diff --git a/common/src/main/java/com/jeesite/common/msg/EmailUtils.java b/common/src/main/java/com/jeesite/common/msg/EmailUtils.java new file mode 100644 index 00000000..af89978c --- /dev/null +++ b/common/src/main/java/com/jeesite/common/msg/EmailUtils.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + */ +package com.jeesite.common.msg; + +import org.apache.commons.mail.HtmlEmail; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jeesite.common.io.PropertiesUtils; + +/** + * 发送电子邮件 + */ +public class EmailUtils { + + private final static Logger logger = LoggerFactory.getLogger(EmailUtils.class); + + /** + * 发送邮件 + * @param toAddress 接收地址 + * @param subject 标题 + * @param content 内容 + * @return + */ + public static boolean send(String toAddress, String subject, String content) { + PropertiesUtils loader = PropertiesUtils.getInstance(); + String fromAddress = loader.getProperty("msg.email.fromAddress"); + String fromPassword = loader.getProperty("msg.email.fromPassword"); + String fromHostName = loader.getProperty("msg.email.fromHostName"); + String sslOnConnect = loader.getProperty("msg.email.sslOnConnect", "false"); + String sslSmtpPort = loader.getProperty("msg.email.sslSmtpPort"); + return send(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content); + } + + /** + * 发送邮件 + * @param toAddress 接收地址 + * @param subject 标题 + * @param content 内容 + * @return + */ + public static boolean send(String fromAddress, String fromPassword, String fromHostName, + String sslOnConnect, String sslSmtpPort, String toAddress, String subject, String content) { + try { + HtmlEmail htmlEmail = new HtmlEmail(); + // 发送地址 + htmlEmail.setFrom(fromAddress); + // 密码校验 + htmlEmail.setAuthentication(fromAddress, fromPassword); + // 发送服务器协议 + htmlEmail.setHostName(fromHostName); + + // SSL + if ("true".equals(sslOnConnect)) { + htmlEmail.setSSLOnConnect(true); + htmlEmail.setSslSmtpPort(sslSmtpPort); + } + + // 接收地址 + htmlEmail.addTo(toAddress); + + // 标题 + htmlEmail.setSubject(subject); + // 内容 + htmlEmail.setMsg(content); + + // 其他信息 + htmlEmail.setCharset("utf-8"); + + // 发送 + htmlEmail.send(); + return true; + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + } + return false; + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/user/AccountController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/user/AccountController.java index 8ef257de..2d1ebec9 100644 --- a/modules/core/src/main/java/com/jeesite/modules/sys/web/user/AccountController.java +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/user/AccountController.java @@ -18,10 +18,10 @@ import org.springframework.web.bind.annotation.ResponseBody; import com.jeesite.common.collect.MapUtils; import com.jeesite.common.config.Global; import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.msg.EmailUtils; +import com.jeesite.common.msg.SmsUtils; import com.jeesite.common.service.ServiceException; import com.jeesite.common.web.BaseController; -import com.jeesite.modules.msg.entity.MsgPush; -import com.jeesite.modules.msg.utils.MsgPushUtils; import com.jeesite.modules.sys.entity.User; import com.jeesite.modules.sys.service.UserService; import com.jeesite.modules.sys.utils.UserUtils; @@ -49,21 +49,21 @@ public class AccountController extends BaseController{ } /** - * 获取短信、邮件验证码 + * 获取找回密码短信、邮件验证码 * @param validCode 图片验证码,防止重复机器人。 * @param validType 验证方式:mobile、email */ - @PostMapping(value = "getValidCode") + @PostMapping(value = "getFpValidCode") @ResponseBody - public String getValidCode(User user, String validCode, String validType, HttpServletRequest request) { + public String getFpValidCode(User user, String validCode, String validType, HttpServletRequest request) { // 校验图片验证码,防止重复机器人。 if (!ValidCodeUtils.validate(request, validCode)){ - return renderResult(Global.FALSE, "验证码不正确或已失效!"); + return renderResult(Global.FALSE, "图片验证码不正确或已失效,请点击图片刷新!"); } if (!"mobile".equals(validType) && !"email".equals(validType)){ return renderResult(Global.FALSE, "非法操作。"); } - User u = userService.getByLoginCode(user); + User u = UserUtils.getByLoginCode(user.getLoginCode()); if(u == null){ return renderResult(Global.FALSE, "登录账号不正确!"); } @@ -106,17 +106,25 @@ public class AccountController extends BaseController{ String validCode = (String)UserUtils.getCache("fpValidCode"); Date date = (Date)UserUtils.getCache("fpLastDate"); + // 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞) + if (!(userCode != null && loginCode != null && loginCode.equals(user.getLoginCode()))){ + return renderResult(Global.FALSE, "请重新获取验证码!"); + } + + // 清理验证码,验证码只允许使用一次。 + UserUtils.removeCache("fpUserCode"); + UserUtils.removeCache("fpLoginCode"); + UserUtils.removeCache("fpValidCode"); + UserUtils.removeCache("fpLastDate"); + // 验证码是否超时 boolean isTimeout = true; String validTime = Global.getConfig("sys.account.validCodeTimeout", "10"); //验证码有效时间(单位分钟,0表示不限制,默认值10) if("0".equals(validTime) || (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 60*Long.parseLong(validTime))){ isTimeout = false; } - - // 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞) - if (!(userCode != null && loginCode != null && loginCode.equals(user.getLoginCode()) - && validCode != null && validCode.equals(fpValidCode) && !isTimeout)){ - return renderResult(Global.FALSE, "验证码不正确或已失效!"); + if (!(validCode != null && validCode.equals(fpValidCode) && !isTimeout)){ + return renderResult(Global.FALSE, "验证码不正确或已失效,请重新获取验证码!"); } // 更新为新密码。 @@ -125,12 +133,6 @@ public class AccountController extends BaseController{ }catch(ServiceException se){ return renderResult(Global.FALSE, se.getMessage()); } - - // 修改密码成功后清理验证码,验证码只允许使用一次。 - UserUtils.removeCache("fpUserCode"); - UserUtils.removeCache("fpLoginCode"); - UserUtils.removeCache("fpValidCode"); - UserUtils.removeCache("fpLastDate"); return renderResult(Global.TRUE, "恭喜你,您的账号 "+loginCode+" 密码修改成功!"); } @@ -143,13 +145,26 @@ public class AccountController extends BaseController{ public String getPwdQuestion(User user, String validCode, HttpServletRequest request) { // 校验图片验证码,防止重复机器人。 if (!ValidCodeUtils.validate(request, validCode)){ - return renderResult(Global.FALSE, "验证码不正确或已失效!"); + return renderResult(Global.FALSE, "图片验证码不正确或已失效,请点击图片刷新!"); } // 账号是否存在验证 - User u = userService.getByLoginCode(user); + User u = UserUtils.getByLoginCode(user.getLoginCode()); if (u == null){ return renderResult(Global.FALSE, "登录账号不正确!"); } + // 操作是否频繁验证, 如果离上次获取验证码小于20秒,则提示操作频繁。 + Date date = (Date)UserUtils.getCache("fpLastDate"); + if (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 20L){ + return renderResult(Global.FALSE, "您当前操作太频繁,请稍等一会再操作!"); + }else{ + UserUtils.putCache("fpLastDate", new Date()); + } + + // 未设置密保 + if (StringUtils.isAnyBlank(u.getPwdQuestion(), u.getPwdQuestion2(), u.getPwdQuestion3())){ + return renderResult(Global.FALSE, "该账号未设置密保问题!"); + } + // 获取保密问题,并缓存 Map data = MapUtils.newHashMap(); data.put("pwdQuestion", u.getPwdQuestion()); @@ -171,9 +186,18 @@ public class AccountController extends BaseController{ public String savePwdByPwdQuestion(User user, HttpServletRequest request) { String userCode = (String)UserUtils.getCache("fpUserCode"); String loginCode = (String)UserUtils.getCache("fpLoginCode"); - User u = userService.getByLoginCode(user); + + // 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞) + if (!(userCode != null && loginCode != null && loginCode.equals(user.getLoginCode()))){ + return renderResult(Global.FALSE, "请重新获取保密问题!"); + } + + // 清理保密问题,每次获取只允许使用一次。 + UserUtils.removeCache("fpUserCode"); + UserUtils.removeCache("fpLoginCode"); // 验证三个密保问题是否正确。 + User u = UserUtils.getByLoginCode(user.getLoginCode()); if (!(u != null && loginCode.equals(user.getLoginCode()) && UserService.validatePassword(user.getPwdQuestionAnswer(), u.getPwdQuestionAnswer()) && UserService.validatePassword(user.getPwdQuestionAnswer2(), u.getPwdQuestionAnswer2()) @@ -187,10 +211,6 @@ public class AccountController extends BaseController{ }catch(ServiceException se){ return renderResult(Global.FALSE, se.getMessage()); } - - // 验证成功后清理缓存。 - UserUtils.removeCache("fpUserCode"); - UserUtils.removeCache("fpLoginCode"); return renderResult(Global.TRUE, "验证通过"); } @@ -199,7 +219,6 @@ public class AccountController extends BaseController{ * @param user 用户信息参数 */ @RequestMapping(value = "registerUser") - @ResponseBody public String registerUser(User user, HttpServletRequest request) { return "modules/sys/account/registerUser"; } @@ -209,12 +228,12 @@ public class AccountController extends BaseController{ * @param user 用户信息参数 * @param validType 验证方式:mobile、email */ - @PostMapping(value = "getRegisterUserValidCode") + @PostMapping(value = "getRegValidCode") @ResponseBody - public String getRegisterUserValidCode(User user, String validCode, String validType, HttpServletRequest request) { + public String getRegValidCode(User user, String validCode, String validType, HttpServletRequest request) { // 校验图片验证码,防止重复机器人。 if (!ValidCodeUtils.validate(request, validCode)){ - return renderResult(Global.FALSE, "验证码不正确或已失效!"); + return renderResult(Global.FALSE, "图片验证码不正确或已失效,请点击图片刷新!"); } if (!"mobile".equals(validType) && !"email".equals(validType)){ return renderResult(Global.FALSE, "非法操作。"); @@ -238,7 +257,7 @@ public class AccountController extends BaseController{ UserUtils.putCache("regLastDate", new Date()); } // 验证用户编码是否存在。 - if (userService.getByLoginCode(user) != null){ + if (UserUtils.getByLoginCode(user.getLoginCode()) != null){ return renderResult(Global.FALSE, "登录账号已存在!"); } // 生成验证码,并缓存。 @@ -271,9 +290,9 @@ public class AccountController extends BaseController{ * @param user 用户信息参数 * @param validType 验证方式:mobile、email */ - @PostMapping(value = "saveRegisterUserByValidCode") + @PostMapping(value = "saveRegByValidCode") @ResponseBody - public String saveRegisterUserByValidCode(User user, String regValidCode, HttpServletRequest request) { + public String saveRegByValidCode(User user, String regValidCode, HttpServletRequest request) { if (!"true".equals(Global.getConfig("sys.account.registerUser"))){ return renderResult(Global.FALSE, "当前系统没有开启注册功能!"); } @@ -285,6 +304,11 @@ public class AccountController extends BaseController{ String mobile = (String)UserUtils.getCache("regMobile"); String validCode = (String)UserUtils.getCache("regValidCode"); Date date = (Date)UserUtils.getCache("regLastDate"); + + // 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞) + if (!(loginCode != null && loginCode.equals(user.getLoginCode()))){ + return renderResult(Global.FALSE, "非法操作。"); + } // 验证码是否超时 boolean isTimeout = true; @@ -292,11 +316,8 @@ public class AccountController extends BaseController{ if("0".equals(validTime) || (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 60*Long.parseLong(validTime))){ isTimeout = false; } - - // 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞) - if (!(loginCode != null && loginCode.equals(user.getLoginCode()) - && validCode != null && validCode.equals(regValidCode) && !isTimeout)){ - return renderResult(Global.FALSE, "验证码不正确或已失效!"); + if (!(validCode != null && validCode.equals(regValidCode) && !isTimeout)){ + return renderResult(Global.FALSE, "验证码不正确或已失效,请重新获取验证码!"); } // 非空数据校验。 @@ -333,33 +354,39 @@ public class AccountController extends BaseController{ * 发送邮件验证码 */ private String sendEmailValidCode(User user, String code, String title){ + String account = user.getEmail(); try { title = user.getUserName() + "(" + user.getLoginCode() + ")"+title+"验证码"; String content = "尊敬的用户,您好!\n\n您的验证码是:" + code +"(请勿透露给其他人)\n\n" - + "请复制后,填写在你的验证码窗口完成验证。\n\n本邮件由系统自动发出,请勿回复。\n\n感谢您的使用。"; - String receiveUserCode = "[CODE]"+user.getEmail(); - MsgPushUtils.push(MsgPush.TYPE_EMAIL, title, content, null, null, receiveUserCode); + + "请复制后,填写在你的验证码窗口完成验证。\n\n本邮件由系统自动发出,请勿回复。\n\n感谢您的使用!"; +// String receiveUserCode = "[CODE]"+account; +// MsgPushUtils.push(MsgPush.TYPE_EMAIL, title, content, null, null, receiveUserCode); + EmailUtils.send(account, title, content); } catch (Exception e) { logger.error(title+"发送邮件错误。", e); return renderResult(Global.FALSE, "系统出现了点问题,错误信息:" + e.getMessage()); } - return renderResult(Global.TRUE, "邮件已发送,请接收并填写验证码!"); + account = account.replaceAll("([\\w\\W]?)([\\w\\W]+)([\\w\\W])(@[\\w\\W]+)", "$1****$3$4"); + return renderResult(Global.TRUE, "验证码已发送到“"+account+"”邮箱账号,请尽快查收!"); } - + /** * 发送短信验证码 */ private String sendSmsValidCode(User user, String code, String title){ + String account = user.getMobile(); try { title = user.getUserName() + "(" + user.getLoginCode() + ")"+title+"验证码"; String content = "您好,您的验证码是:" + code +"(请勿透露给其他人)感谢您的使用。"; - String receiveUserCode = "[CODE]"+user.getMobile(); - MsgPushUtils.push(MsgPush.TYPE_SMS, title, content, null, null, receiveUserCode); +// String receiveUserCode = "[CODE]"+account; +// MsgPushUtils.push(MsgPush.TYPE_SMS, title, content, null, null, receiveUserCode); + SmsUtils.send(content, account); } catch (Exception e) { logger.error(title+"发送短信错误。", e); return renderResult(Global.FALSE, "系统出现了点问题,错误信息:" + e.getMessage()); } - return renderResult(Global.TRUE, "短信已发送,请接收并填写验证码!"); + account = account.replaceAll("(\\d{3})(\\d+)(\\d{3})","$1****$3"); + return renderResult(Global.TRUE, "验证码已发送到“"+account+"”的手机号码,请尽快查收!"); } } diff --git a/modules/core/src/main/resources/config/jeesite-core.yml b/modules/core/src/main/resources/config/jeesite-core.yml index e555da80..32916a12 100644 --- a/modules/core/src/main/resources/config/jeesite-core.yml +++ b/modules/core/src/main/resources/config/jeesite-core.yml @@ -155,6 +155,13 @@ user: # 多租户模式(SAAS模式)(专业版) useCorpModel: false + # 自助账号服务 + account: + # 注册用户 + registerUser: + enabled: true + userTypes: 0, 1 + # 任务调度(个人版+) job: @@ -421,10 +428,10 @@ msg: # 短信网关 sms: beanName: smsSendService - url: http://localhost:80/msg/sendSms - data: account=demo&pswd=demo&product= - prefix: ~ - suffix: 【JeeSite】 + url: http://lehuo520.cn/a/sms/api + data: username=jeesite&password=jeesite.com + prefix: 【JeeSite】 + suffix: ~ # 微信相关 weixin: diff --git a/modules/core/src/main/resources/views/modules/sys/account/forgetPwd.html b/modules/core/src/main/resources/views/modules/sys/account/forgetPwd.html new file mode 100644 index 00000000..e789b9bb --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/account/forgetPwd.html @@ -0,0 +1,187 @@ +<% layout('/layouts/default.html', {title: '忘记密码', libs: ['validate'], bodyClass: 'login-page'}){ %> +<% include('/include/upgrade.html'){} // 如果客户浏览器版本过低,则显示浏览器升级提示。 %> + + + +<% var productName = @Global.getConfig('productName'), productVersion = @Global.getConfig('productVersion'); %> + +<% } %> + + + + \ No newline at end of file