找回密码和注册用户敏感信息加密处理

This commit is contained in:
thinkgem
2020-09-29 16:07:38 +08:00
parent ac4c092a1c
commit 5e346c6d72
9 changed files with 81 additions and 32 deletions

View File

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.codec.DesUtils;
import com.jeesite.common.collect.MapUtils; import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.config.Global; import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils; import com.jeesite.common.lang.StringUtils;
@@ -145,13 +146,17 @@ public class AccountController extends BaseController{
if (s != null) { if (s != null) {
return s; return s;
} }
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
if (StringUtils.isNotBlank(secretKey)){
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
}
// 更新为新密码 // 更新为新密码
try{ try{
userService.updatePassword(userCode, user.getPassword()); userService.updatePassword(userCode, user.getPassword());
}catch(ServiceException se){ }catch(ServiceException se){
return renderResult(Global.FALSE, se.getMessage()); return renderResult(Global.FALSE, se.getMessage());
} }
return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码修改成功!", user.getUserCode())); return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码找回成功!", user.getLoginCode()));
} }
/** /**
@@ -299,6 +304,14 @@ public class AccountController extends BaseController{
return renderResult(Global.FALSE, text("请重新获取保密问题!")); return renderResult(Global.FALSE, text("请重新获取保密问题!"));
} }
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
if (StringUtils.isNotBlank(secretKey)){
user.setPwdQuestionAnswer(DesUtils.decode(user.getPwdQuestionAnswer(), secretKey));
user.setPwdQuestionAnswer2(DesUtils.decode(user.getPwdQuestionAnswer2(), secretKey));
user.setPwdQuestionAnswer3(DesUtils.decode(user.getPwdQuestionAnswer3(), secretKey));
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
}
// 验证三个密保问题是否正确。 // 验证三个密保问题是否正确。
User u = UserUtils.getByLoginCode(user.getLoginCode()); User u = UserUtils.getByLoginCode(user.getLoginCode());
if (!(u != null && loginCode.equals(user.getLoginCode()) if (!(u != null && loginCode.equals(user.getLoginCode())
@@ -318,8 +331,8 @@ public class AccountController extends BaseController{
// 更新密码后,清理缓存 // 更新密码后,清理缓存
UserUtils.removeCache("fpUserCode"); UserUtils.removeCache("fpUserCode");
UserUtils.removeCache("fpLoginCode"); UserUtils.removeCache("fpLoginCode");
return renderResult(Global.TRUE, text("验证通过")); return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码找回成功!", user.getLoginCode()));
} }
/** /**
@@ -466,6 +479,10 @@ public class AccountController extends BaseController{
} }
u.setLoginCode(loginCode); u.setLoginCode(loginCode);
u.setUserName(userName); u.setUserName(userName);
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
if (StringUtils.isNotBlank(secretKey)){
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
}
u.setPassword(user.getPassword()); u.setPassword(user.getPassword());
u.setEmail(email); u.setEmail(email);
u.setMobile(mobile); u.setMobile(mobile);
@@ -483,7 +500,7 @@ public class AccountController extends BaseController{
UserUtils.removeCache("regValidCode"); UserUtils.removeCache("regValidCode");
UserUtils.removeCache("regLastDate"); UserUtils.removeCache("regLastDate");
return renderResult(Global.TRUE, text("恭喜你,您的账号 "+u.getLoginCode()+" 注册成功!")); return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 注册成功!", u.getLoginCode()));
} }
/** /**

View File

@@ -18,7 +18,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
@@ -46,7 +45,7 @@ public class LoginController extends BaseController{
/** /**
* 登录页面 * 登录页面
*/ */
@RequestMapping(value = "login", method = RequestMethod.GET) @RequestMapping(value = "login")
public String login(HttpServletRequest request, HttpServletResponse response, Model model) { public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
// 地址中如果包含JSESSIONID则跳转一次去掉JSESSIONID信息。 // 地址中如果包含JSESSIONID则跳转一次去掉JSESSIONID信息。
if (StringUtils.containsIgnoreCase(request.getRequestURI(), ";JSESSIONID=")){ if (StringUtils.containsIgnoreCase(request.getRequestURI(), ";JSESSIONID=")){

View File

@@ -371,7 +371,7 @@ shiro:
# accessControlAllowOrigin: http://demo.jeesite.com # accessControlAllowOrigin: http://demo.jeesite.com
# accessControlAllowOrigin: '*' # accessControlAllowOrigin: '*'
# 允许跨域访问时 CORS可以使用的方法和响应 # 允许跨域访问时 CORS可以使用的方法和
# accessControlAllowMethods: GET, POST, OPTIONS # accessControlAllowMethods: GET, POST, OPTIONS
# accessControlAllowHeaders: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With # accessControlAllowHeaders: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With

View File

@@ -75,7 +75,24 @@ $(function(){
$('#forgetForm').validate({ $('#forgetForm').validate({
ignore: ":hidden", ignore: ":hidden",
submitHandler: function(form) { submitHandler: function(form) {
js.ajaxSubmitForm($(form), function(data){ var $form = $(form),
action = $form.attr('action'),
data = $form.serializeArray(),
key = window.secretKey||$('#loginKey').data('key');
if (key != ''){
for (var i=0, l=data.length; i<l; i++){
if (data[i].name == 'pwdQuestionAnswer'){
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer').val(), key);
}else if (data[i].name == 'pwdQuestionAnswer2'){
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer2').val(), key);
}else if (data[i].name == 'pwdQuestionAnswer3'){
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer3').val(), key);
}else if (data[i].name == 'password'){
data[i].value = DesUtils.encode($('#fp_password').val(), key);
}
}
}
js.ajaxSubmit(action, data, function(data, status, xhr){
if (data.result == "true"){ if (data.result == "true"){
alert(data.message); alert(data.message);
location = ctx + '/login'; location = ctx + '/login';

View File

@@ -67,7 +67,18 @@ $(function(){
$('#registerForm').validate({ $('#registerForm').validate({
ignore: ":hidden", ignore: ":hidden",
submitHandler: function(form) { submitHandler: function(form) {
js.ajaxSubmitForm($(form), function(data){ var $form = $(form),
action = $form.attr('action'),
data = $form.serializeArray(),
key = window.secretKey||$('#loginKey').data('key');
if (key != ''){
for (var i=0, l=data.length; i<l; i++){
if (data[i].name == 'password'){
data[i].value = DesUtils.encode($('#reg_password').val(), key);
}
}
}
js.ajaxSubmit(action, data, function(data, status, xhr){
if (data.result == "true"){ if (data.result == "true"){
alert(data.message); alert(data.message);
location = ctx + '/login'; location = ctx + '/login';

View File

@@ -41,24 +41,24 @@
</div> </div>
<div class="form-group has-feedback fp-element fp-question"> <div class="form-group has-feedback fp-element fp-question">
<span class="fa fa-question-circle form-control-feedback"></span> <span class="fa fa-question-circle form-control-feedback"></span>
<input type="text" name="pwdQuestionAnswer" class="form-control required" <input type="text" id="fp_pwdQuestionAnswer" name="pwdQuestionAnswer"
data-msg-required="请填写答案1." placeholder="答案1 " /> class="form-control required" data-msg-required="请填写答案1." placeholder="答案1 " />
</div> </div>
<div class="form-group has-feedback fp-element fp-question"> <div class="form-group has-feedback fp-element fp-question">
问题2<span id="fp_q2"></span> 问题2<span id="fp_q2"></span>
</div> </div>
<div class="form-group has-feedback fp-element fp-question"> <div class="form-group has-feedback fp-element fp-question">
<span class="fa fa-question-circle form-control-feedback"></span> <span class="fa fa-question-circle form-control-feedback"></span>
<input type="text" name="pwdQuestionAnswer2" class="form-control required" <input type="text" id="fp_pwdQuestionAnswer2" name="pwdQuestionAnswer2"
data-msg-required="请填写答案2." placeholder="答案2" /> class="form-control required" data-msg-required="请填写答案2." placeholder="答案2" />
</div> </div>
<div class="form-group has-feedback fp-element fp-question"> <div class="form-group has-feedback fp-element fp-question">
问题3<span id="fp_q3"></span> 问题3<span id="fp_q3"></span>
</div> </div>
<div class="form-group has-feedback fp-element fp-question"> <div class="form-group has-feedback fp-element fp-question">
<span class="fa fa-question-circle form-control-feedback"></span> <span class="fa fa-question-circle form-control-feedback"></span>
<input type="text" name="pwdQuestionAnswer3" class="form-control required" <input type="text" id="fp_pwdQuestionAnswer3" name="pwdQuestionAnswer3"
data-msg-required="请填写答案3." placeholder="答案3" /> class="form-control required" data-msg-required="请填写答案3." placeholder="答案3" />
</div> </div>
<div class="form-group has-feedback clearfix"> <div class="form-group has-feedback clearfix">
<strong>设置新密码:</strong> <strong>设置新密码:</strong>
@@ -93,11 +93,11 @@
</div> </div>
<div class="login-copyright"> <div class="login-copyright">
&copy; ${@DateUtils.getYear()} ${@Global.getConfig('productName')} - Powered By <a &copy; ${@DateUtils.getYear()} ${@Global.getConfig('productName')} - Powered By <a
href="http://jeesite.com">JeeSite ${@Global.getProperty('jeesiteVersion')}</a> id="loginKey" data-key="${@Global.getConfig('shiro.loginSubmit.secretKey')}"
href="http://jeesite.com" >JeeSite ${@Global.getProperty('jeesiteVersion')}</a>
</div> </div>
</div> </div>
<% } %> <% } %>
<script>var secretKey = '${@Global.getConfig("shiro.loginSubmit.secretKey")}';</script>
<script src="${ctxStatic}/jquery-toastr/2.1/toastr.min.js?${_version}"></script>
<script src="${ctxStatic}/common/des.js?${_version}"></script> <script src="${ctxStatic}/common/des.js?${_version}"></script>
<script src="${ctxStatic}/jquery-toastr/2.1/toastr.min.js?${_version}"></script>
<script src="${ctxStatic}/modules/sys/forgetPwd.js?${_version}"></script> <script src="${ctxStatic}/modules/sys/forgetPwd.js?${_version}"></script>

View File

@@ -89,9 +89,11 @@
</div> </div>
<div class="login-copyright"> <div class="login-copyright">
&copy; ${@DateUtils.getYear()} ${@Global.getConfig('productName')} - Powered By <a &copy; ${@DateUtils.getYear()} ${@Global.getConfig('productName')} - Powered By <a
href="http://jeesite.com">JeeSite ${@Global.getProperty('jeesiteVersion')}</a> id="loginKey" data-key="${@Global.getConfig('shiro.loginSubmit.secretKey')}"
href="http://jeesite.com" >JeeSite ${@Global.getProperty('jeesiteVersion')}</a>
</div> </div>
</div> </div>
<% } %> <% } %>
<script src="${ctxStatic}/common/des.js?${_version}"></script>
<script src="${ctxStatic}/jquery-toastr/2.1/toastr.min.js?${_version}"></script> <script src="${ctxStatic}/jquery-toastr/2.1/toastr.min.js?${_version}"></script>
<script src="${ctxStatic}/modules/sys/registerUser.js?${_version}"></script> <script src="${ctxStatic}/modules/sys/registerUser.js?${_version}"></script>

View File

@@ -311,16 +311,22 @@ $('#sex input').on('ifCreated ifChecked', function(){
$("#newPassword").strength(); $("#newPassword").strength();
$("#inputFormPwd").validate({ $("#inputFormPwd").validate({
submitHandler: function(form){ submitHandler: function(form){
var oldPassword = $('#oldPassword').val(), var $form = $(form),
newPassword = $('#newPassword').val(), action = $form.attr('action'),
confirmNewPassword = $('#confirmNewPassword').val(), data = $form.serializeArray(),
secretKey = '${@Global.getConfig("shiro.loginSubmit.secretKey")}'; key = '${@Global.getConfig("shiro.loginSubmit.secretKey")}';
if (secretKey != ''){ if (key != ''){
$('#oldPassword').val(DesUtils.encode(oldPassword, secretKey)); for (var i=0, l=data.length; i<l; i++){
$('#newPassword').val(DesUtils.encode(newPassword, secretKey)); if (data[i].name == 'oldPassword'){
$('#confirmNewPassword').val(DesUtils.encode(confirmNewPassword, secretKey)); data[i].value = DesUtils.encode($('#oldPassword').val(), key);
}else if (data[i].name == 'newPassword'){
data[i].value = DesUtils.encode($('#newPassword').val(), key);
}else if (data[i].name == 'confirmNewPassword'){
data[i].value = DesUtils.encode($('#confirmNewPassword').val(), key);
}
}
} }
js.ajaxSubmitForm($(form), function(data){ js.ajaxSubmit(action, data, function(data, status, xhr){
js.showMessage(data.message); js.showMessage(data.message);
if(data.result == Global.TRUE){ if(data.result == Global.TRUE){
if ('${parameter.url}'!=''){ if ('${parameter.url}'!=''){
@@ -330,9 +336,6 @@ $("#inputFormPwd").validate({
} }
} }
}, "json"); }, "json");
$('#oldPassword').val(oldPassword);
$('#newPassword').val(newPassword);
$('#confirmNewPassword').val(confirmNewPassword);
} }
}); });
// 密保问题 // 密保问题

View File

@@ -483,7 +483,7 @@ shiro:
## accessControlAllowOrigin: http://demo.jeesite.com ## accessControlAllowOrigin: http://demo.jeesite.com
## accessControlAllowOrigin: '*' ## accessControlAllowOrigin: '*'
# #
# # 允许跨域访问时 CORS可以使用的方法和响应 # # 允许跨域访问时 CORS可以使用的方法和
# accessControlAllowMethods: GET, POST, OPTIONS # accessControlAllowMethods: GET, POST, OPTIONS
# accessControlAllowHeaders: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With # accessControlAllowHeaders: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With
# #