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