找回密码功能

pull/137/head
ruibaby 2019-03-03 11:18:24 +08:00
parent c2e7bce7bc
commit f7d40db7b1
5 changed files with 367 additions and 9 deletions

View File

@ -60,6 +60,10 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
.addPathPatterns("/backup/**")
.excludePathPatterns("/admin/login")
.excludePathPatterns("/admin/getLogin")
.excludePathPatterns("/admin/findPassword")
.excludePathPatterns("/admin/sendResetPasswordEmail")
.excludePathPatterns("/admin/toResetPassword")
.excludePathPatterns("/admin/resetPassword")
.excludePathPatterns("/static/**");
registry.addInterceptor(installInterceptor)
.addPathPatterns("/**")

View File

@ -13,6 +13,7 @@ import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
@ -77,6 +78,9 @@ public class AdminController extends BaseController {
@Autowired
private LocaleMessageUtil localeMessageUtil;
@Autowired
private MailService mailService;
/**
*
*
@ -193,6 +197,107 @@ public class AdminController extends BaseController {
}
}
/**
*
*
* @return String
*/
@GetMapping(value = "/findPassword")
public String findPassword() {
return "admin/admin_findpassword";
}
/**
*
*
* @param userName
* @param email
* @return JsonResult
*/
@PostMapping(value = "/sendResetPasswordEmail")
@ResponseBody
public JsonResult sendResetPasswordEmail(@RequestParam(value = "userName") String userName,
@RequestParam(value = "email") String email,
HttpSession session) {
final User user = userService.findUser();
if (StrUtil.isEmpty(userName) || StrUtil.isEmpty(email)) {
return JsonResult.fail("请输入完整信息!");
}
if (!user.getUserEmail().equals(email) || !user.getUserName().equals(userName)) {
return JsonResult.fail("用户名或电子邮箱错误,请确定你的身份!");
}
try {
long time = System.currentTimeMillis();
String randomString = RandomUtil.randomString(10);
String code = SecureUtil.md5(time + randomString);
StrBuilder url = new StrBuilder(OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
url.append("/admin/toResetPassword?code=");
url.append(code);
mailService.sendMail(user.getUserEmail(), "请根据该链接重置你的博客密码", "请点击该链接重置你的密码:" + url);
session.setAttribute("resetPasswordCode", code);
return JsonResult.success("邮件发送成功,请登录您的邮箱进行下一步操作");
} catch (Exception e) {
return JsonResult.fail("邮件发送失败,请确定已经配置好了发信服务器信息");
}
}
/**
*
*
* @param code code
* @return String
*/
@GetMapping(value = "/toResetPassword")
public String toResetPassword(@RequestParam(value = "code", defaultValue = "") String code,
Model model,
HttpSession session) {
final String sessionCode = (String) session.getAttribute("resetPasswordCode");
if (StrUtil.isEmpty(code)) {
this.renderNotFound();
}
if (!sessionCode.equals(code)) {
model.addAttribute("isRight", false);
} else {
model.addAttribute("isRight", true);
}
model.addAttribute("code", code);
return "admin/admin_resetpassword";
}
/**
*
*
* @param password password
* @param definePassword definePassword
* @return String
*/
@PostMapping(value = "/resetPassword")
@ResponseBody
public JsonResult resetPassword(@RequestParam(value = "password") String password,
@RequestParam(value = "definePassword") String definePassword,
@RequestParam(value = "code") String code,
HttpSession session) {
final String sessionCode = (String) session.getAttribute("resetPasswordCode");
if (null == sessionCode) {
return JsonResult.fail("不允许该操作!");
}
if (!StrUtil.equals(code, sessionCode)) {
return JsonResult.fail("不允许该操作!");
}
if (StrUtil.isEmpty(password) || StrUtil.isEmpty(definePassword)) {
return JsonResult.fail("请输入完整信息!");
}
if (!StrUtil.equals(password, definePassword)) {
return JsonResult.fail("两次密码不一样!");
}
final User user = userService.findUser();
user.setUserPass(SecureUtil.md5(password));
userService.update(user);
userService.updateUserNormal();
session.removeAttribute("resetPasswordCode");
return JsonResult.success("重置密码成功!");
}
/**
* 退 session
*

View File

@ -0,0 +1,126 @@
<#compress >
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<title>${options.blog_title!} | 找回密码</title>
<link rel="stylesheet" href="/static/halo-backend/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/halo-backend/plugins/animate/animate.min.css">
<link rel="stylesheet" href="/static/halo-backend/plugins/toast/css/jquery.toast.min.css">
<link rel="stylesheet" href="/static/halo-backend/css/style.min.css">
<style>
body {
background-color: #f5f5f5
}
* {
outline: 0
}
label {
color: #4b1c0f
}
.findPasswordForm {
max-width: 380px;
margin-top: 10%
}
.findPasswordLogo {
font-size: 56px;
text-align: center;
margin-bottom: 25px;
font-weight: 500;
color: #444;
text-shadow: #b2baba .1em .1em .2em
}
.findPasswordBody {
padding: 20px;
background-color: #fff;
-o-box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1);
box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1)
}
.alert{
-o-box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1);
box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1)
}
.send-button {
background-color: #fff;
border-radius: 0;
border: 1px solid #000;
transition: all .5s ease-in-out
}
.send-button:hover {
border: 1px solid #fff;
background-color: #000;
color: #fff
}
.form-group {
margin-bottom: 24px;
}
#userName,#email {
border-radius: 0
}
</style>
</head>
<body>
<div class="container findPasswordForm">
<div class="findPasswordLogo animated fadeInUp">
Halo <small style="font-size: 14px;">找回密码</small>
</div>
<div class="alert alert-info animated fadeInUp" role="alert" style="animation-delay: 0.1s">
请输入您的用户名和电子邮箱地址。您会收到一封包含创建新密码链接的电子邮件(请确定已经配置好了发信服务器信息)。
</div>
<div class="findPasswordBody animated">
<form>
<div class="form-group animated fadeInUp" style="animation-delay: 0.2s">
<input type="text" class="form-control" name="userName" id="userName" placeholder="用户名">
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.3s">
<input type="text" class="form-control" name="email" id="email" placeholder="电子邮箱地址">
</div>
<button type="button" id="btnFindPassword" data-loading-text="发送中..." onclick="findPassword()" class="btn btn-block send-button animated fadeInUp" style="animation-delay: 0.4s;outline: none;">发送邮件</button>
</form>
</div>
</div>
</body>
<script src="/static/halo-common/jquery/jquery.min.js"></script>
<script src="/static/halo-backend/plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/halo-backend/plugins/toast/js/jquery.toast.min.js"></script>
<script src="/static/halo-backend/js/halo.min.js"></script>
<script>
var halo = new $.halo();
var heading = "<@spring.message code='common.text.tips' />";
function findPassword() {
var btnFindPassword = $('#btnFindPassword');
var name = $("#userName");
var email = $("#email");
btnFindPassword.button('loading');
if (email.val() === "" || name.val() === "") {
halo.showMsg("请输入完整信息!", 'info', 2000);
btnFindPassword.button('reset');
} else {
$.post('/admin/sendResetPasswordEmail',{
'userName': name.val(),
'email': email.val()
},function (data) {
if (data.code === 1) {
halo.showMsgAndRedirect(data.msg,'success',1000,"/admin/login")
} else {
halo.showMsg(data.msg,'error',2000);
}
btnFindPassword.button('reset');
},'JSON');
}
}
</script>
</html>
</#compress>

View File

@ -11,7 +11,7 @@
<link rel="stylesheet" href="/static/halo-backend/plugins/toast/css/jquery.toast.min.css">
<link rel="stylesheet" href="/static/halo-backend/css/style.min.css">
<style>
body{background-color:#f5f5f5}*{outline:0}label{color:#4b1c0f}.loginForm{max-width:380px;margin-top:10%}.loginLogo{font-size:56px;text-align:center;margin-bottom:25px;font-weight:500;color:#444;text-shadow:#b2baba .1em .1em .2em}.loginBody{padding:20px;background-color:#fff;-o-box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1);box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1)}.login-button{background-color:#fff;border-radius:0;border:1px solid #000;transition:all .5s ease-in-out}.login-button:hover{border:1px solid #fff;background-color:#000;color:#fff}.form-group{padding-bottom:25px}#loginName,#loginPwd{border-radius:0}.control{padding-bottom:5px}
body{background-color:#f5f5f5}*{outline:0}label{color:#4b1c0f}.loginForm{max-width:380px;margin-top:10%}.loginLogo{font-size:56px;text-align:center;margin-bottom:25px;font-weight:500;color:#444;text-shadow:#b2baba .1em .1em .2em}.loginBody{padding:20px;background-color:#fff;-o-box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1);box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1)}.login-button{background-color:#fff;border-radius:0;border:1px solid #000;transition:all .5s ease-in-out}.login-button:hover{border:1px solid #fff;background-color:#000;color:#fff}.form-group{margin-bottom: 24px;}#loginName,#loginPwd{border-radius:0}.control{padding-bottom:5px}
</style>
</head>
<body>
@ -28,14 +28,11 @@
<div class="form-group animated fadeInUp" style="animation-delay: 0.2s">
<input type="password" class="form-control" name="loginPwd" id="loginPwd" placeholder="<@spring.message code='login.form.loginPwd' />" autocomplete="current-password">
</div>
<#--<div class="row control animated fadeInUp" style="animation-delay: 0.3s">-->
<#--<div class="col-xs-6">-->
<#--<label for="remember"><input type="checkbox" id="remember"> <span style="color: #000;font-weight: lighter">记住我</span></label>-->
<#--</div>-->
<#--<div class="col-xs-6 pull-right text-right">-->
<#--<a href="#" style="color: #000;">忘记密码?</a>-->
<#--</div>-->
<#--</div>-->
<div class="row control animated fadeInUp" style="animation-delay: 0.3s">
<div class="col-xs-6 pull-right text-right">
<a href="/admin/findPassword" style="color: #000;">忘记密码?</a>
</div>
</div>
<button type="button" id="btnLogin" data-loading-text="<@spring.message code='login.btn.logining' />" class="btn btn-block login-button animated fadeInUp" onclick="doLogin()" style="animation-delay: 0.4s;outline: none;"><@spring.message code='login.btn.login' /></button>
</form>
</div>

View File

@ -0,0 +1,126 @@
<#compress >
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<title>${options.blog_title!} | 重置密码</title>
<link rel="stylesheet" href="/static/halo-backend/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/halo-backend/plugins/animate/animate.min.css">
<link rel="stylesheet" href="/static/halo-backend/plugins/toast/css/jquery.toast.min.css">
<link rel="stylesheet" href="/static/halo-backend/css/style.min.css">
<style>
body {
background-color: #f5f5f5
}
* {
outline: 0
}
label {
color: #4b1c0f
}
.findPasswordForm {
max-width: 380px;
margin-top: 10%
}
.findPasswordLogo {
font-size: 56px;
text-align: center;
margin-bottom: 25px;
font-weight: 500;
color: #444;
text-shadow: #b2baba .1em .1em .2em
}
.findPasswordBody {
padding: 20px;
background-color: #fff;
-o-box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1);
box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1)
}
.alert{
-o-box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1);
box-shadow: -4px 7px 46px 2px rgba(0,0,0,.1)
}
.reset-button {
background-color: #fff;
border-radius: 0;
border: 1px solid #000;
transition: all .5s ease-in-out
}
.reset-button:hover {
border: 1px solid #fff;
background-color: #000;
color: #fff
}
.form-group {
margin-bottom: 24px;
}
#password,#definePassword {
border-radius: 0
}
</style>
</head>
<body>
<div class="container findPasswordForm">
<div class="findPasswordLogo animated fadeInUp">
Halo <small style="font-size: 14px;">重置密码</small>
</div>
<#if isRight>
<div class="findPasswordBody animated">
<form>
<div class="form-group animated fadeInUp" style="animation-delay: 0.1s">
<input type="password" class="form-control" name="password" id="password" placeholder="新密码">
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.2s">
<input type="password" class="form-control" name="definePassword" id="definePassword" placeholder="确认新密码">
</div>
<button type="button" id="btnResetPassword" onclick="resetPassword()" class="btn btn-block reset-button animated fadeInUp" style="animation-delay: 0.3s;outline: none;">重置密码</button>
</form>
</div>
<#else>
<div class="alert alert-info animated fadeInUp" role="alert" style="animation-delay: 0.1s">该链接已失效,请重新上一步操作</div>
</#if>
</div>
</body>
<#if isRight>
<script src="/static/halo-common/jquery/jquery.min.js"></script>
<script src="/static/halo-backend/plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/halo-backend/plugins/toast/js/jquery.toast.min.js"></script>
<script src="/static/halo-backend/js/halo.min.js"></script>
<script>
var halo = new $.halo();
var heading = "<@spring.message code='common.text.tips' />";
function resetPassword() {
var password = $('#password');
var definePassword = $('#definePassword');
if (password.val() === "" || definePassword.val() === "") {
halo.showMsg("请输入完整信息!", 'info', 2000);
} else {
$.post('/admin/resetPassword',{
'password': password.val(),
'definePassword': definePassword.val(),
'code': '${code}'
},function (data) {
if (data.code === 1) {
halo.showMsgAndRedirect(data.msg,'success',1000,"/admin/login")
} else {
halo.showMsg(data.msg,'error',2000);
}
},'JSON');
}
}
</script>
</#if>
</html>
</#compress>