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); } }