You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.5 KiB
125 lines
4.5 KiB
|
1 week ago
|
package com.student.service;
|
||
|
|
|
||
|
|
import com.student.bean.LoginLog;
|
||
|
|
import com.student.bean.RememberToken;
|
||
|
|
import com.student.bean.User;
|
||
|
|
import com.student.dao.LogDao;
|
||
|
|
import com.student.dao.RememberTokenDao;
|
||
|
|
import com.student.dao.UserDao;
|
||
|
|
import com.student.dao.impl.LogDaoImpl;
|
||
|
|
import com.student.dao.impl.RememberTokenDaoImpl;
|
||
|
|
import com.student.dao.impl.UserDaoImpl;
|
||
|
|
import com.student.util.PasswordUtil;
|
||
|
|
|
||
|
|
import java.util.Calendar;
|
||
|
|
import java.util.Date;
|
||
|
|
|
||
|
|
public class AuthService {
|
||
|
|
|
||
|
|
private static final int MAX_FAIL_COUNT = 5;
|
||
|
|
private static final int LOCK_MINUTES = 30;
|
||
|
|
private static final int REMEMBER_DAYS = 7;
|
||
|
|
|
||
|
|
private final UserDao userDao;
|
||
|
|
private final LogDao logDao;
|
||
|
|
private final RememberTokenDao tokenDao;
|
||
|
|
|
||
|
|
public AuthService() {
|
||
|
|
this(new UserDaoImpl(), new LogDaoImpl(), new RememberTokenDaoImpl());
|
||
|
|
}
|
||
|
|
|
||
|
|
AuthService(UserDao userDao, LogDao logDao, RememberTokenDao tokenDao) {
|
||
|
|
this.userDao = userDao;
|
||
|
|
this.logDao = logDao;
|
||
|
|
this.tokenDao = tokenDao;
|
||
|
|
}
|
||
|
|
|
||
|
|
public User login(String username, String password, String ip) {
|
||
|
|
User user = userDao.findByUsername(username);
|
||
|
|
if (user == null) {
|
||
|
|
saveLoginLog(null, username, ip, 0, "用户不存在");
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (isLocked(user)) {
|
||
|
|
saveLoginLog(user.getId(), username, ip, 0, "账户已锁定");
|
||
|
|
throw new RuntimeException("账户已锁定,请稍后再试");
|
||
|
|
}
|
||
|
|
if (!PasswordUtil.verify(password, user.getSalt(), user.getPassword())) {
|
||
|
|
int failCount = (user.getFailCount() != null ? user.getFailCount() : 0) + 1;
|
||
|
|
userDao.updateFailCount(user.getId(), failCount);
|
||
|
|
if (failCount >= MAX_FAIL_COUNT) {
|
||
|
|
Calendar cal = Calendar.getInstance();
|
||
|
|
cal.add(Calendar.MINUTE, LOCK_MINUTES);
|
||
|
|
userDao.lockUser(user.getId(), cal.getTime());
|
||
|
|
saveLoginLog(user.getId(), username, ip, 0, "密码错误,账户已锁定");
|
||
|
|
throw new RuntimeException("密码错误次数过多,账户已锁定30分钟");
|
||
|
|
}
|
||
|
|
saveLoginLog(user.getId(), username, ip, 0, "密码错误");
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (user.getStatus() != null && user.getStatus() == User.STATUS_PENDING) {
|
||
|
|
saveLoginLog(user.getId(), username, ip, 0, "账户待审核");
|
||
|
|
throw new RuntimeException("账户待审核,请等待管理员审批");
|
||
|
|
}
|
||
|
|
if (user.getStatus() != null && (user.getStatus() == User.STATUS_SUSPEND
|
||
|
|
|| user.getStatus() == User.STATUS_DROPPED)) {
|
||
|
|
saveLoginLog(user.getId(), username, ip, 0, "账户已停用");
|
||
|
|
throw new RuntimeException("账户已停用");
|
||
|
|
}
|
||
|
|
userDao.updateFailCount(user.getId(), 0);
|
||
|
|
userDao.lockUser(user.getId(), null);
|
||
|
|
saveLoginLog(user.getId(), username, ip, 1, "登录成功");
|
||
|
|
user.setPassword(null);
|
||
|
|
return user;
|
||
|
|
}
|
||
|
|
|
||
|
|
public String createRememberToken(int userId) {
|
||
|
|
tokenDao.deleteByUser(userId);
|
||
|
|
RememberToken token = new RememberToken();
|
||
|
|
token.setUserId(userId);
|
||
|
|
token.setToken(PasswordUtil.generateToken());
|
||
|
|
Calendar cal = Calendar.getInstance();
|
||
|
|
cal.add(Calendar.DAY_OF_MONTH, REMEMBER_DAYS);
|
||
|
|
token.setExpireTime(cal.getTime());
|
||
|
|
tokenDao.save(token);
|
||
|
|
return token.getToken();
|
||
|
|
}
|
||
|
|
|
||
|
|
public User loginByToken(String token) {
|
||
|
|
RememberToken rt = tokenDao.findByToken(token);
|
||
|
|
if (rt == null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
User user = userDao.findById(rt.getUserId());
|
||
|
|
if (user != null) {
|
||
|
|
user.setPassword(null);
|
||
|
|
}
|
||
|
|
return user;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void logoutRemember(int userId) {
|
||
|
|
tokenDao.deleteByUser(userId);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void cleanExpiredTokens() {
|
||
|
|
tokenDao.deleteExpired();
|
||
|
|
}
|
||
|
|
|
||
|
|
private boolean isLocked(User user) {
|
||
|
|
if (user.getLockUntil() == null) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return user.getLockUntil().after(new Date());
|
||
|
|
}
|
||
|
|
|
||
|
|
private void saveLoginLog(Integer userId, String username, String ip, int result, String message) {
|
||
|
|
LoginLog log = new LoginLog();
|
||
|
|
log.setUserId(userId);
|
||
|
|
log.setUsername(username);
|
||
|
|
log.setIp(ip);
|
||
|
|
log.setResult(result);
|
||
|
|
log.setMessage(message);
|
||
|
|
logDao.saveLoginLog(log);
|
||
|
|
}
|
||
|
|
}
|