mirror of https://github.com/halo-dev/halo
👽 加强用户登录安全,超过登录次数限制登录
parent
3ae12ba69f
commit
f57d8254e0
19
README.md
19
README.md
|
@ -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
|
||||
|
|
|
@ -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/**");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -27,7 +27,7 @@ spring:
|
|||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
show-sql: false
|
||||
show-sql: true
|
||||
database-platform: org.hibernate.dialect.H2Dialect
|
||||
|
||||
# freemarker配置
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue