Java實現用戶每天登錄次數的限制


正常的用戶每天的登錄退出不會太頻繁,遇到頻繁的登錄則很可能是黑客行為。對於黑客行為,我們可以使用登錄次數限制來應對。本文將介紹如何限制用戶每天的登錄次數,包括:“記錄當天用戶賬號的登錄次數”、“用戶進行登錄請求時,檢查當天賬號的登錄次數”、“用戶正常退出登錄,更新登錄次數”。

1、記錄當天用戶賬號的登錄次數。

定義hashmap類型的屬性mapLoginCountIn1Day,用來存儲當前用戶賬號(key)和登錄賬號的次數(value):

	protected static Map<String, Object> mapLoginCountIn1Day = new HashMap<String, Object>();

定義另一個hashmap類型的屬性mapLoginDay,用戶存儲當前日期(key)和mapLoginCountIn1Day(value):

	protected static Map<String, Object> mapLoginDay = new HashMap<String, Object>();

2、用戶進行登錄請求時,檢查當天賬號的登錄次數。

在checkLoginCount方法檢查登錄次數:

	@SuppressWarnings("unchecked")
	protected boolean checkLoginCount(Object phone, ErrorInfo ecOut) {
		boolean bLoginToManyTimes = false; // 檢查Staff是否登錄次數過多
		lock.writeLock().lock();
		try {
			BxConfigGeneral cgMaxRequestCountIn1Day = (BxConfigGeneral) CacheManager.getCache(BaseAction.DBName_Public, EnumCacheType.ECT_BXConfigGeneral).read1(BaseCache.MaxLoginCountIn1Day, BaseBO.SYSTEM, ecOut, BaseAction.DBName_Public);
			int MAX_LoginCountIn1Day = Integer.valueOf(cgMaxRequestCountIn1Day.getValue());
			// MAX_LoginCountIn1Day = 5;
			String dateForDay = sdfLoginCountIn1Day.format(new Date());
			if (mapLoginDay.get(dateForDay) == null) {
				mapLoginDay.clear();
				mapLoginCountIn1Day.put(String.valueOf(phone), 1);
				mapLoginDay.put(dateForDay, mapLoginCountIn1Day);
			} else {
				mapLoginCountIn1Day = (Map<String, Object>) mapLoginDay.get(dateForDay);
				if (mapLoginCountIn1Day.get(phone) == null) {
					mapLoginCountIn1Day.put(String.valueOf(phone), 1);
				} else {
					int currentLoginCountIn1Day = (int) mapLoginCountIn1Day.get(phone);
					mapLoginCountIn1Day.put(String.valueOf(phone), ++currentLoginCountIn1Day);
					if (currentLoginCountIn1Day >= MAX_LoginCountIn1Day) {
						if (currentLoginCountIn1Day % MAX_LoginCountIn1Day == 0) {
							logger.error("手機號碼" + phone + "當天已超過登錄次數,已登錄" + currentLoginCountIn1Day + "次");
						}
						bLoginToManyTimes = true;
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		lock.writeLock().unlock();
		//
		if (bLoginToManyTimes) {
			return false;// 從此禁止用戶再次登錄。那么,用戶什么時候可以再次登錄?1、重啟Tomcat。2、給OP開發一個接口。(后面再做)
		}
		return true;
	}

首先判斷在當前日期有沒有用戶登錄過mapLoginDay.get(dateForDay),沒有登錄過則清空mapLoginDay,並將該賬號的登錄次數設為1,緩存到mapLoginDay。

如果當前日期有用戶登錄過:

判斷當前用戶有無登錄過,沒有登錄過將該賬號的登錄次數設為1,緩存到mapLoginDay。登錄過就將賬號的登錄次數加1。如果登錄次數大於設定的值MAX_LoginCountIn1Day(可以在數據庫定義、讀取),就阻止用戶在當天的登錄。

3、用戶正常退出登錄,更新登錄次數。

用戶退出登錄請求接口:

	@RequestMapping(value = "/logoutEx", produces = "plain/text; charset=UTF-8", method = RequestMethod.GET)
	@ResponseBody
	public String logout(HttpSession session) {
		if (!canCallCurrentAction(session, BaseAction.EnumUserScope.STAFF.getIndex())) {
			logger.debug("無權訪問本Action");
			return null;
		}

		Company company = getCompanyFromSession(session);

		Staff staff = (Staff) session.getAttribute(EnumSession.SESSION_Staff.getName()); // ...定義常量
		logger.info("服務器的登出,staff=" + staff);
		Map<String, Object> params = new HashMap<String, Object>();
		if (staff != null) {
			// 更新Staff登錄次數
			updateLoginCount(staff.getPhone());
			params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_NoError.toString());
			Pos pos = (Pos) session.getAttribute(EnumSession.SESSION_POS.getName());
			if (pos != null && pos.getID() != BaseAction.INVALID_POS_ID) {
				sendLogoutMsgToWx(staff, company);
			}
			// if (staff.getInt3() == 1 || Staff.DEFINE_GET_RoleID(staff.getInt1()) == 1) {
			// sendMsgToWx(staff, company);
			// }
		} else {
			logger.info("其他錯誤");
			params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_OtherError.toString());
		}
		params.put(KEY_HTMLTable_Parameter_msg, staffBO.getLastErrorMessage());
		logger.info("返回的數據=" + params);

		EnumSession.clearAllSession(session);
		session.invalidate();

		return JSONObject.fromObject(params, JsonUtil.jsonConfig).toString();
	}

updateLoginCount方法更新登錄次數:

	@SuppressWarnings("unchecked")
	protected void updateLoginCount(Object phone) {
		lock.writeLock().lock();
		//
		try {
			String dateForDay = sdfLoginCountIn1Day.format(new Date());
			if (mapLoginDay.get(dateForDay) != null) {
				mapLoginCountIn1Day = (Map<String, Object>) mapLoginDay.get(dateForDay);
				if (mapLoginCountIn1Day.get(phone) != null) {
					int currentLoginCountIn1Day = (int) mapLoginCountIn1Day.get(phone);
					mapLoginCountIn1Day.put(String.valueOf(phone), --currentLoginCountIn1Day);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		//
		lock.writeLock().unlock();
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM