当前位置: 首页 > article >正文

基于若依前后分离版-用户密码错误锁定

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";@Autowiredprivate RedisTemplate<Object, Object> redisTemplate;@Autowiredprivate 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);}}
http://www.lryc.cn/news/2401334.html

相关文章:

  • 论文速读《DexWild:野外机器人策略的灵巧人机交互》
  • Bug问题
  • 【数据结构】5. 双向链表
  • 【Linux手册】冯诺依曼体系结构
  • Mobile App UI自动化locator
  • PaloAlto-Expedition OS命令注入漏洞复现(CVE-2025-0107)
  • (LeetCode 每日一题) 1061. 按字典序排列最小的等效字符串 (并查集)
  • linux 安装mysql8.0;支持国产麒麟,统信uos系统
  • C#实现远程锁屏
  • 历史记录隐藏的安全风险
  • SpringBoot3整合MySQL8的注意事项
  • 网络安全大模型理解
  • 智语心桥:当AI遇上“星星的孩子”,科技如何点亮沟通之路?
  • itop-3568开发板机器视觉opencv开发手册-图像绘制-画线
  • 【高频面试题】快慢指针及相关应用
  • sudo docker exec -it backend bash 以交互方式(interactive)进入正在运行的 Docker 容器的命令行环境
  • [论文阅读] 人工智能 | 当AI遇见绿色软件工程:可持续AI实践的研究新方向
  • [论文阅读] 人工智能 | 用大语言模型抓虫:如何让网络协议实现与RFC规范对齐
  • 浅析EXCEL自动连接PowerBI的模板
  • DeepSeek 赋能金融反洗钱:AI 驱动的风险监测革新之路
  • java32
  • 【Redis】zset 类型
  • 从Gartner报告看Atlassian在生成式AI领域的创新路径与实践价值
  • Kafka 安装教程(支持 Windows / Linux / macOS)
  • OpenCV种的cv::Mat与Qt种的QImage类型相互转换
  • 机器学习——什么时候使用决策树
  • llm-d:面向Kubernetes的高性能分布式LLM推理框架
  • 前端没有“秦始皇“,但可以做跨端的王[特殊字符]
  • Flutter如何支持原生View
  • mongodb源码分析session异步接受asyncSourceMessage()客户端流变Message对象