👽 加强用户登录安全,超过登录次数限制登录

pull/1/head
RYAN0UP_ 2018-03-24 20:51:45 +08:00
parent 3ae12ba69f
commit f57d8254e0
9 changed files with 158 additions and 30 deletions

View File

@ -48,12 +48,25 @@ Fast,simple,powerful blog system powered by Java.
## Thanks 感谢
Halo的诞生离不开下面这些开源项目:
Halo的诞生离不开下面这些项目
- [IntelliJ IDEA](https://www.jetbrains.com/idea/)个人认为强大的Java IDE没有之一
- [Spring Boot](https://github.com/spring-projects/spring-boot)Spring的微服务框架
- [Freemarker](https://freemarker.apache.org/):模板引擎,使页面静态化
- [H2 Database](https://github.com/h2database/h2database):嵌入式数据库,无需安装
- [Druid](https://github.com/alibaba/druid):阿里的数据源
- [Druid](https://github.com/alibaba/druid):阿里开发的连接池
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git)不需要写sql语句的持久层框架
- [Ehcache](http://www.ehcache.org/):缓存框架
- [Lombok](https://www.projectlombok.org/):让代码更简洁
- [Apache Commons](http://commons.apache.org/)非常好用的Java工具库
- [oh-my-email](https://github.com/biezhi/oh-my-email)可能是最小的Java邮件发送库了支持抄送、附件、模板等
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE)基于Bootstrap的后台模板
- [Bootstrap](https://github.com/twbs/bootstrap.git)使用最广泛的前端ui框架
- [Animate](https://github.com/daneden/animate.css.git)非常好用的css动效库
- [Editor.md](https://github.com/pandao/editor.md.git)Markdown前端编辑器遗憾作者弃坑了
- [Bootstrap-FileInput](https://github.com/kartik-v/bootstrap-fileinput.git):个人认为最好用的上传组件,没有之一
- [Font-awesome](https://github.com/FortAwesome/Font-Awesome.git):使用最广泛的字体图标库
- [Jquery](https://github.com/jquery/jquery.git)使用最广泛的JavaScript框架
- [Layer](https://github.com/sentsin/layer.git):个人认为最实用最好看的弹出层组件,没有之一
- [Jquery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin):消息提示组件
- [Pjax](https://github.com/defunkt/jquery-pjax.git)pushState + ajax = pjax

View File

@ -39,11 +39,13 @@ public class MvcConfiguration implements WebMvcConfigurer {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/login")
.excludePathPatterns("/admin/getLogin");
//registry.addInterceptor(installInterceptor)
// .addPathPatterns("/**")
// .excludePathPatterns("/install")
// .excludePathPatterns("/install/do");
.excludePathPatterns("/admin/getLogin")
.excludePathPatterns("/static/**");
registry.addInterceptor(installInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/install")
.excludePathPatterns("/install/do")
.excludePathPatterns("/static/**");
}
/**

View File

@ -4,6 +4,7 @@ import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author : RYAN0UP
@ -24,28 +25,49 @@ public class User implements Serializable{
@Id
@GeneratedValue
private Long userId;
/**
*
*/
private String userName;
/**
*
*/
private String userDisplayName;
/**
*
*/
private String userPass;
/**
*
*/
private String userEmail;
/**
*
*/
private String userAvatar;
/**
*
*/
private String userDesc;
/**
*
*/
private String loginEnable;
/**
*
*/
private Date loginLast;
/**
*
*/
private Integer loginError;
}

View File

@ -2,6 +2,7 @@ package cc.ryanc.halo.service;
import cc.ryanc.halo.model.domain.User;
import java.util.Date;
import java.util.List;
/**
@ -50,4 +51,30 @@ public interface UserService {
* @return user
*/
User findByUserIdAndUserPass(Long userId,String userPass);
/**
*
*
* @param enable enable
*/
void updateUserLoginEnable(String enable);
/**
*
*
* @param lastDate lastDate
*/
User updateUserLoginLast(Date lastDate);
/**
*
*
* @param error error
*/
Integer updateUserLoginError();
/**
*
*/
User updateUserNormal();
}

View File

@ -6,6 +6,7 @@ import cc.ryanc.halo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
@ -75,4 +76,55 @@ public class UserServiceImpl implements UserService {
public User findByUserIdAndUserPass(Long userId, String userPass) {
return userRepository.findByUserIdAndUserPass(userId,userPass);
}
/**
*
*
* @param enable enable
*/
@Override
public void updateUserLoginEnable(String enable) {
User user = this.findAllUser().get(0);
user.setLoginEnable(enable);
userRepository.save(user);
}
/**
*
*
* @param lastDate lastDate
*/
@Override
public User updateUserLoginLast(Date lastDate) {
User user = this.findAllUser().get(0);
user.setLoginLast(lastDate);
userRepository.save(user);
return user;
}
/**
*
*
* @param error error
*/
@Override
public Integer updateUserLoginError() {
User user = this.findAllUser().get(0);
user.setLoginError(user.getLoginError()+1);
userRepository.save(user);
return user.getLoginError();
}
/**
*
*/
@Override
public User updateUserNormal() {
User user = this.findAllUser().get(0);
user.setLoginEnable("true");
user.setLoginError(0);
user.setLoginLast(new Date());
userRepository.save(user);
return user;
}
}

View File

@ -115,30 +115,43 @@ public class AdminController extends BaseController{
*/
@PostMapping(value = "/getLogin")
@ResponseBody
public boolean getLogin(@ModelAttribute("loginName") String loginName,
public String getLogin(@ModelAttribute("loginName") String loginName,
@ModelAttribute("loginPwd") String loginPwd,
HttpSession session){
String status = "false";
try {
List<User> users = null;
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
Matcher matcher = patternEmail.matcher(loginName);
if(matcher.find()){
users = userService.userLoginByEmail(loginName,HaloUtil.getMD5(loginPwd));
User aUser = userService.findAllUser().get(0);
User user = null;
if("false".equals(aUser.getLoginEnable())){
status = "disable";
}else{
users = userService.userLoginByName(loginName,HaloUtil.getMD5(loginPwd));
}
if(null!=users){
session.setAttribute(HaloConst.USER_SESSION_KEY, users.get(0));
log.info("用户["+ users.get(0).getUserName()+"]登录成功!");
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_SUCCESS,HaloUtil.getIpAddr(request), HaloUtil.getDate()));
return true;
}else{
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_ERROR,HaloUtil.getIpAddr(request),new Date()));
//验证是否是邮箱登录
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
Matcher matcher = patternEmail.matcher(loginName);
if(matcher.find()){
user = userService.userLoginByEmail(loginName,HaloUtil.getMD5(loginPwd)).get(0);
}else{
user = userService.userLoginByName(loginName,HaloUtil.getMD5(loginPwd)).get(0);
}
if(aUser==user){
session.setAttribute(HaloConst.USER_SESSION_KEY, user);
//重置用户的登录状态为正常
userService.updateUserNormal();
userService.updateUserLoginLast(new Date());
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_SUCCESS,HaloUtil.getIpAddr(request), HaloUtil.getDate()));
status = "true";
}
}
}catch (Exception e){
Integer errorCount = userService.updateUserLoginError();
if(errorCount>=5){
userService.updateUserLoginEnable("false");
}
userService.updateUserLoginLast(new Date());
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_ERROR,HaloUtil.getIpAddr(request),new Date()));
log.error("登录失败!:"+e.getMessage());
}
return false;
return status;
}
/**

View File

@ -22,7 +22,6 @@ public class InstallInterceptor implements HandlerInterceptor {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File installFile = new File(basePath.getAbsolutePath(), "install.lock");
if(installFile.exists()){
response.sendRedirect("/");
return true;
}
response.sendRedirect("/install");

View File

@ -27,7 +27,7 @@ spring:
jpa:
hibernate:
ddl-auto: update
show-sql: false
show-sql: true
database-platform: org.hibernate.dialect.H2Dialect
# freemarker配置

View File

@ -62,8 +62,8 @@
'loginName': name,
'loginPwd': pwd
},
success: function (data) {
if(data==true){
success: function (status) {
if(status=="true"){
$.toast({
text: "登录成功!",
heading: '提示',
@ -80,10 +80,10 @@
window.location.href="/admin";
}
});
}else if(data=="wait"){
}else if(status=="disable"){
$('.login-body').addClass('animate shake');
$.toast({
text: "密码错误已达到5次30分钟后再试",
text: "密码错误已达到5次10分钟后再试",
heading: '提示',
icon: 'error',
showHideTransition: 'fade',