增加登录次数限制

This commit is contained in:
pengjie 2023-10-12 13:37:14 +08:00
parent ae03cc1dc3
commit 2a59eed3e1
4 changed files with 97 additions and 29 deletions

View File

@ -6,10 +6,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@ -229,6 +226,16 @@ public class RedisRepository {
return resultStr;
}
/**
* 根据key过期时间
*
* @param key the key
* @return the string
*/
public Long getExpire(final String key) {
return redisTemplate.opsForValue().getOperations().getExpire(key);
}
/**
* 根据key获取对象

View File

@ -18,6 +18,11 @@ public interface CacheConstants {
*/
String USER_DETAILS = "user_details:";
/**
* 锁定用户信息缓存
*/
String USER_LOCK = "user_lock:";
/**
* 角色信息缓存
*/

View File

@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@ -58,6 +59,9 @@ public class SystemUserAuthController {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ISystemRoleService systemRoleService;
@ -77,11 +81,16 @@ public class SystemUserAuthController {
@PostMapping(value = "/login")
public Result<SystemUserAuthDto> login(@ApiIgnore @RequestBody SystemUser systemUser) {
Result<SystemUserAuthDto> result = new Result<SystemUserAuthDto>();
// 检查账户是否已被锁定
if (jwtTokenProvider.checkLock(systemUser.getAccount()) >=5 ) {
result.error500("账号已被锁定,还有" + DateUtil.formatBetween(jwtTokenProvider.getExpire(systemUser.getAccount()) * 1000L) + "解锁");
return result;
}
SystemUser user = systemUserService.getOne(Wrappers.<SystemUser>lambdaQuery()
.eq(SystemUser::getAccount, systemUser.getAccount())
.eq(SystemUser::getShowPassword, systemUser.getShowPassword()));
SystemUserAuthDto userInfo = new SystemUserAuthDto();
checkLogin(user, userInfo, result);
checkLogin(user, userInfo, result, systemUser.getAccount());
if (result.getCode() != CommonConstant.SC_INTERNAL_SERVER_ERROR_500) {
String token = jwtTokenProvider.createToken(userInfo.getAccount(), 3600 * 24 * 1000L);
userInfo.setToken(token);
@ -156,7 +165,7 @@ public class SystemUserAuthController {
SystemUser user = systemUserService.getOne(Wrappers.<SystemUser>lambdaQuery()
.eq(SystemUser::getAccount, userName));
SystemUserAuthDto userInfo = new SystemUserAuthDto();
checkLogin(user, userInfo, result);
checkLogin(user, userInfo, result, userName);
if (result.getCode() != CommonConstant.SC_INTERNAL_SERVER_ERROR_500) {
userInfo.setToken(token);
userInfo.setIsEngineering(systemUserDataScopeService.count(Wrappers.<SystemUserDataScope>lambdaQuery()
@ -167,35 +176,42 @@ public class SystemUserAuthController {
return result;
}
private void checkLogin(SystemUser user, SystemUserAuthDto userInfo, Result<SystemUserAuthDto> result) {
private void checkLogin(SystemUser user, SystemUserAuthDto userInfo, Result<SystemUserAuthDto> result, String account) {
if (user != null) {
BeanUtils.copyProperties(user, userInfo);
}
if(user==null || user.getAccountType() == 5) {
result.error500("登录名或密码错误");
} else if(userInfo.getState() == 0) {
result.error500("账号未启用,请联系管理员");
} else if(userInfo.getAccountType() != 1) {
Government government = governmentService.getGovByUser(userInfo.getAccountType(), userInfo.getSn());
Government parent = governmentService.getOne(Wrappers.<Government>lambdaQuery().eq(Government::getGovernmentId, government.getParentId()));
if (parent.getExpireTime() != null && DateUtil.endOfDay(parent.getExpireTime()).before(new Date())) {
parent.setState(0);
governmentService.updateById(parent);
}
if (government.getExpireTime() != null && DateUtil.endOfDay(government.getExpireTime()).before(new Date())) {
government.setState(0);
governmentService.updateById(government);
}
if (government == null || government.getState() == 0 || parent.getState() == 0) {
result.error500("住建局账号异常,请联系管理员");
}
if (!userInfo.getIsManager()) {
Long roleId = systemRoleService.getByUserId(userInfo.getUserId());
if (roleId == null) {
result.error500("角色未启用,请联系管理员");
//记录登录失败次数一次性累计失败五次将锁定账户6小时
jwtTokenProvider.saveLock(account);
int count = 5 - jwtTokenProvider.checkLock(account);
result.error500("登录名或密码错误, " + count + "次输入错误后将被锁定");
} else {
if(userInfo.getState() == 0) {
result.error500("账号未启用,请联系管理员");
} else if(userInfo.getAccountType() != 1) {
Government government = governmentService.getGovByUser(userInfo.getAccountType(), userInfo.getSn());
Government parent = governmentService.getOne(Wrappers.<Government>lambdaQuery().eq(Government::getGovernmentId, government.getParentId()));
if (parent.getExpireTime() != null && DateUtil.endOfDay(parent.getExpireTime()).before(new Date())) {
parent.setState(0);
governmentService.updateById(parent);
}
if (government.getExpireTime() != null && DateUtil.endOfDay(government.getExpireTime()).before(new Date())) {
government.setState(0);
governmentService.updateById(government);
}
if (government == null || government.getState() == 0 || parent.getState() == 0) {
result.error500("住建局账号异常,请联系管理员");
}
if (!userInfo.getIsManager()) {
Long roleId = systemRoleService.getByUserId(userInfo.getUserId());
if (roleId == null) {
result.error500("角色未启用,请联系管理员");
}
}
userInfo.setProjectDateAuth(government.getProjectDateAuth());
}
userInfo.setProjectDateAuth(government.getProjectDateAuth());
//登录名密码输入正确清楚登陆失败记录
jwtTokenProvider.clearLock(user.getAccount());
}
}

View File

@ -128,4 +128,44 @@ public class JwtTokenProvider {
throw new RuntimeException(e);
}
}
public int checkLock(String username) {
try {
Object num = redisRepository.get(CacheConstants.USER_LOCK + username);
return num == null ? 0 : (int) num;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void saveLock(String username) {
try {
Object num = redisRepository.get(CacheConstants.USER_LOCK + username);
if (num == null) {
redisRepository.set(CacheConstants.USER_LOCK + username, 1);
} else {
redisRepository.set(CacheConstants.USER_LOCK + username, (int)num + 1);
}
redisRepository.setExpire(CacheConstants.USER_LOCK + username, redisRepository.get(CacheConstants.USER_LOCK + username), 60 * 60 * 6);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void clearLock(String username) {
try {
redisRepository.del(CacheConstants.USER_LOCK + username);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public long getExpire(String username) {
try {
return redisRepository.getExpire(CacheConstants.USER_LOCK + username);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}