使用Ehcache缓存在用户输错n次账户密码之后冻结m小时的简单实现
博客专区 > Mr_Tank_ 的博客 > 博客详情
使用Ehcache缓存在用户输错n次账户密码之后冻结m小时的简单实现
Mr_Tank_ 发表于1年前
使用Ehcache缓存在用户输错n次账户密码之后冻结m小时的简单实现
  • 发表于 1年前
  • 阅读 133
  • 收藏 8
  • 点赞 2
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 我们经常会看到有些系统,为了提高账户安全性,会在用户输入n次密码时候锁定对应的账户一段时间,避免暴力破解用户密码

我们经常会看到有些系统,为了提高账户安全性,会在用户输入n次密码时候锁定对应的账户一段时间,这样可以避免暴力破解用户密码(说实话这样行不行我也不知道)。不知道正确的实现姿势应该是什么样的,但是我们可以利用缓存来简单实现这个功能,先来一盘代码:

0、初始化配置

为每个用户初始化保存到缓存中的key

    private int MAX_FAIL_TIMES = 3;// 默认最多允许出错次数
	private int FROZEN_TIME = 1;// 默认冻结时间,单位[小时]
	private String COUNT_KEY;// 失败次数缓存Key
	private String TIME_KEY;// 冻结时间缓存Key
	private long USERID;// 冻结的用户ID

	private String CACHE_REGION = "Account";

	public static FrozenAccountTool init(String key, long userId, int maxFailTimes, int frozenTime) {

		FrozenAccountTool frozenAccountTool = new FrozenAccountTool();

		frozenAccountTool.USERID = userId;
		frozenAccountTool.COUNT_KEY = key + "#USER#COUNT#" + frozenAccountTool.USERID;
		frozenAccountTool.TIME_KEY = key + "#USER#TIME#" + frozenAccountTool.USERID;
		frozenAccountTool.MAX_FAIL_TIMES = maxFailTimes > 0 ? maxFailTimes : frozenAccountTool.MAX_FAIL_TIMES;
		frozenAccountTool.FROZEN_TIME = frozenTime > 0 ? frozenTime : frozenAccountTool.FROZEN_TIME;
		return frozenAccountTool;
	}

1、记录验证失败次数

首先需要记录用户输错的次数,每次验证失败的时候,失败次数+1

    // 失败次数+1
	public void failCountIncrease() {
		int failCount = GetFailCount();
		_SetFailCount(failCount + 1);
	}

GetFailCount() 方法用于从缓存里面取出当前失败的次数,具体实现如下:

        // 获取失败次数
	public int GetFailCount() {
		return EhcacheUtil.get(CACHE_REGION, COUNT_KEY) == null ? 1 : (Integer) EhcacheUtil.get(CACHE_REGION, COUNT_KEY);
	}

再看一下 _SetFailCount() 方法,这里是为了在失败次数大于最大失败次数的时候设置当前时间为锁定时间,用于后面判断解锁时间是否已经到了:

        // 設置失败次数
	private void _SetFailCount(int failCount) {
		EhcacheUtil.put(CACHE_REGION, COUNT_KEY, failCount);
		if (failCount >= MAX_FAIL_TIMES) {
			SetFrozenTime();
		}
	}

2、判断账户是否被冻结

<1>.首先判断当前时间点距离被锁定的时间是否大于设定锁定的时间,大于表示已经解锁,重置锁定设置的缓存数据;注:这个要先判断,要不然锁定之后就永远无法解锁了

<2>.如果时间还没到设定锁定的时间则判断当前失败次数是否大于最大失败次数,大于表示已经被锁定

public boolean IsFrozen() {
		long frozenTimeMillis = GetFrozenTime();
		System.out.println(new Date() + ">锁定时间:" + GetFrozenTime());
		System.out.println(new Date() + ">当前错误次数:" + GetFailCount());
		if (frozenTimeMillis > 0 && (System.currentTimeMillis() - frozenTimeMillis > FROZEN_TIME * 60 * 60 * 1000)) {
			System.out.println(new Date() + ">锁定时间到,解锁账号");
			resetFrozen();
			return false;
		} else if (GetFailCount() >= MAX_FAIL_TIMES) {
			System.out.println(new Date() + ">账号已锁定..");
			return true;
		}
		System.out.println(new Date() + ">账号未锁定..");
		return false;
	}

> 温馨提示:以上的方法命名不符合java规范,大写是为了避免get、set、is开头的方法和javabean规范的冲突,仅供参考

** 3、如何使用 **

输入图片说明

4、测试代码

        FrozenAccountTool frozenAccountTool1 = FrozenAccountTool.init("GETCASH", 593115, 5, 1);
		for (int i = 0; i < 5; i++) {
			frozenAccountTool1.failCountIncrease();
			Thread.sleep(2000);
		}
		boolean result = true;
		while (result) {
			result = frozenAccountTool1.IsFrozen();
			Thread.sleep(5000);
		}

5、测试结果 (这里只设置锁定了0.01个小时)

输入图片说明

6、最后

我们可以看到开源中国社区的登陆也是用了同样的原理,用户输错2次密码的时候会出现验证码,输错密码次数大于限定的次数后该email账号会被锁定两个小时

(1)输错两次密码后,万恶的验证码出现了

输入图片说明

(2)输错N次之后

输入图片说明

不相信可以自己去试一下哦,似乎可以做什么坏事的样子

关于Ehcache工具类和其他代码已经托管到:https://git.oschina.net

标签: Ehcache 冻结账号
共有 人打赏支持
Mr_Tank_
粉丝 222
博文 31
码字总数 14028
×
Mr_Tank_
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: