sys_config配置参数
user.password.maxRetryCount:最大错误次数
user.password.lockTime:锁定时长
//SysLoginController
//登录
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = sysPasswordService.validate(loginBody, loginService);
ajax.put(Constants.TOKEN, token);
return ajax;
}
//解锁
@PostMapping("/unlock")
public AjaxResult unlock(String loginName) {
AjaxResult ajax = AjaxResult.success();
sysPasswordService.clearLoginRecordCache(loginName);
return ajax;
}
package com.ruoyi.web.controller.system.service;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.ISysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
@Component
public class LockService {
public static final String LOGINRECORDCACHE = "loginRecordCache";
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Autowired
private ISysConfigService configService;
public String validate(LoginBody loginBody, SysLoginService loginService) {
String loginName = loginBody.getUsername();
String maxRetryCount = configService.selectConfigByKey("user.password.maxRetryCount");
Long fz = Long.parseLong(configService.selectConfigByKey("user.password.lockTime"));
Integer retryCount = (Integer)redisTemplate.opsForValue().get(LOGINRECORDCACHE + loginName);
if (retryCount == null) {
retryCount = new Integer (0);
}
if (StringUtils.isNotBlank(maxRetryCount)) {
retryCount++;
if (retryCount > Integer.parseInt(maxRetryCount)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, fz)));
throw new ServiceException("重试次数超过限制:" + Integer.parseInt(maxRetryCount)+"次,请"+fz+"分钟后重试");
}
}
// 生成令牌
try {
String token = loginService.login(base64Decode(loginBody.getUsername()), base64Decode(loginBody.getPassword()), loginBody.getCode(),
loginBody.getUuid());
clearLoginRecordCache(loginName);
return token;
} catch (Exception e){
redisTemplate.opsForValue().set(LOGINRECORDCACHE + loginName, retryCount, fz, TimeUnit.MINUTES);
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount)));
throw e;
}
}
private final String base64Decode(String base64EncodedString){
// 获取Base64解码器
Base64.Decoder decoder = Base64.getDecoder();
// 解码Base64字符串
byte[] decodedBytes = decoder.decode(base64EncodedString);
// 将解码后的字节数组转换为字符串(假设原始数据是文本)
return new String(decodedBytes);
}
public void clearLoginRecordCache(String loginName) {
redisTemplate.delete(LOGINRECORDCACHE + loginName);
}
}