用戶登錄錯誤次數限制、並實現:錯誤登錄次數、登錄錯誤間隔時間、封禁時間,參數的可配

1、可配參數說明:

錯誤登錄次數:用戶可“連續”輸入錯誤的次數;

登錄錯誤間隔時間:第一次錯誤~最後一次錯誤的間隔時間(此處用分鐘做計算);

封禁時間:登錄錯誤次數達到上限後,禁止用戶登錄的時長(此處用分鐘做計算);


2、表設計:

h_login_miss:記錄登錄次數和狀態-主表

h_login_log:記錄登錄信息-附表-主要記錄了每個用戶的登錄時間(排除“登錄錯誤間隔時間”之前的錯誤登錄記錄),用於實現(登錄錯誤間隔時間的可配化--如果需求是“每日錯誤登錄限制”,此表可省略

CREATE TABLE `h_login_miss` (

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `employee_id` bigint(19) NOT NULL COMMENT '用戶id',
  `miss_number` int(11) unsigned zerofill DEFAULT NULL COMMENT '登錄失敗次數(登錄成功就清0 失敗就+1)',
  `miss_time` datetime DEFAULT NULL COMMENT '鎖定登錄時間:這個時間如果大於當前時間 則不能登錄',
  `miss_flag` char(1) DEFAULT NULL COMMENT '鎖定標誌:0未鎖定狀態  1代表鎖定狀態 ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='登錄錯誤限制表';

CREATE TABLE `h_login_log` (

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `employee_id` bigint(19) NOT NULL COMMENT '用戶id',
  `flag` char(1) DEFAULT NULL COMMENT '登錄狀態(0:登錄成功  1:登錄失敗)',
  `ip_address` varchar(255) DEFAULT NULL COMMENT 'ip地址',
  `login_time` datetime DEFAULT NULL COMMENT '登錄時間',
  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=261 DEFAULT CHARSET=utf8 COMMENT='登錄記錄表';


3、代碼:

此處只寫出MVC層代碼和核心業務代碼;(--使用切面,在登錄模塊做驗證)

@Aspect
@Configuration
public class LoginAspect extends BaseController{
    private final Logger logger = Logger.getLogger(this.getClass());

    // 定義切點Pointcut
    @Pointcut("execution(* com.credit.controller.shiro.LoginController.loginPost(String , String , String ,*)) && args(username,password,code,session)")
    public void excudeService(String username, String password, String code, HttpSession session) {}


    /**
     *
     * @TitledoAround
     * @Description: 環繞觸發
     */
    @Around("excudeService(username,  password, code,session)")
    public Object doAround(ProceedingJoinPoint pjp,String username, String password, String code, HttpSession session) throws Throwable {
        Boolean flag = true;
        Object resultStr = null;

        if (StringUtils.isBlank(username)) {
            return renderError("用戶名不能爲空");
        }
        if (StringUtils.isBlank(password)) {
            return renderError("密碼不能爲空");
        }
        //驗證是否含可能登錄
        //此處調用的boot代碼,可直接更改爲,方法調用(具體方法在下面的代碼中)
        String url = FileHelpper.map.get("url.userUrl")+ FileHelpper.map.get("loginMiss.judgeMiss");
        StringBuffer str = new StringBuffer();
        str.append("loginName=" + username);

        logger.info("請求參數:"+url+"?"+str);
        String result = HttpReqUtil.sendPost(url,str.toString());
        logger.info("返回結果集:"+result);
        if (StringUtils.isBlank(result)){
            return renderError("不存在該用戶");
        }
        JSONObject jsonObject = JSONObject.parseObject(result);
        Integer resultNo = jsonObject.getInteger("resultNo");
        if (resultNo == 0) {
            resultStr = pjp.proceed();//登錄目標方法 result的值就是被攔截方法的返回值
            //獲取request
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            //設置IP地址--登錄成功後記錄用戶登錄數據
            String ipAddress = IPUtils.getIpAddr(request);
            String url2 = FileHelpper.map.get("url.userUrl")+ FileHelpper.map.get("loginMiss.importMiss");
            StringBuffer str2 = new StringBuffer();
            str2.append("loginName=" + username);
            str2.append("&flag=" + (((Result)resultStr).getResultNo()==0));
            str2.append("&ipAddress=" + ipAddress);
            logger.info("請求參數:"+url2+"?"+str2);
            String result2 = HttpReqUtil.sendPost(url2,str2.toString());
            logger.info("返回結果集:"+result2);

            return resultStr;
        }else {
            return renderError("不存在該用戶");
        }
    }

}
/**
 * 登錄錯誤或正確處理
 * @param employeeId
 * @param flag  true正確   false用戶輸入錯誤
 * @return
 */
@Override
public int importMiss(Long employeeId,Boolean flag) {
    LoginMiss login = loginMissMapper.findLoginByEmployeeId(employeeId);
    if (login == null) {
        if (flag) {
            addLoginMiss(employeeId, 0);
        } else {
            addLoginMiss(employeeId, 1);
        }
    }

    if (flag) {
        login.setMissFlag("0");
        login.setMissNumber(0);
        login.setMissTime(new Date());
    } else {
        if (DateHelper.compareDate(login.getMissTime(),new Date())==1){
            return 1;
        }
        //注:此處是獲取3個可配參數
        String missNum = enumValueMapper.getValue(Integer.valueOf(FileHelpper.map.get("enumValue.missNum")));//錯誤登陸限制次數
        String intervalTime = enumValueMapper.getValue(Integer.valueOf(FileHelpper.map.get("enumValue.intervalTime")));//錯誤登陸間隔(單位:分鐘)
        String forbidTime = enumValueMapper.getValue(Integer.valueOf(FileHelpper.map.get("enumValue.forbidTime")));//錯誤登陸禁止時間(單位:分鐘)

        //排除超過禁止時間的錯誤登陸信息
        List<LoginLog> logs = loginLogMapper.findMissLog(employeeId, login.getMissNumber());
        for (int i = 0; i < logs.size(); i++) {
            LoginLog log = logs.get(i);

            if (DateHelper.getDaysbytwoDate2(new Date(), log.getLoginTime()) > Integer.valueOf(intervalTime)) {
                logs.remove(i);
            }
        }
        login.setMissNumber(logs.size());//設置錯誤次數

        if (login.getMissNumber() + 1 > Integer.valueOf(missNum)) {//需要禁止登錄
            login.setMissFlag("1");
            try {
                login.setMissTime(DateHelper.addDate(new Date(), Long.valueOf(forbidTime)));//加上對應的禁止時間
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            login.setMissNumber(login.getMissNumber() + 1);
            login.setMissFlag("0");
            login.setMissTime(new Date());
        }
    }
    return loginMissMapper.updateByPrimaryKeySelective(login);
}

/**
 * 判斷是否在鎖定時間 即:是否可以登錄
 */
@Override
public String judgeMiss(Long employeeId) {
    LoginMiss login = loginMissMapper.findLoginByEmployeeId(employeeId);
    if (login == null) {
        addLoginMiss(employeeId, 0);
    }
    if (DateHelper.compareDate(new Date(),login.getMissTime())==1){
        return null;
    }else {//不可以登錄
        return DateHelper.dateFormat1(login.getMissTime());
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章