深入解析:基于若依前后分离版-用户密码错误锁定

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; @Componentpublic class LockService {    public static final String LOGINRECORDCACHE = "loginRecordCache";      @Autowired    private RedisTemplate 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);    } }
posted @ 2025-07-24 11:02  yfceshi  阅读(129)  评论(0)    收藏  举报