84669 orang belajar
152542 orang belajar
20005 orang belajar
5487 orang belajar
7821 orang belajar
359900 orang belajar
3350 orang belajar
180660 orang belajar
48569 orang belajar
18603 orang belajar
40936 orang belajar
1549 orang belajar
1183 orang belajar
32909 orang belajar
我要限制用户一小时内登陆只能密码输错12次,如果在最近一小时内累计密码错误超过12次就直接不能登录,如何用memcache实现,不用mysql,因为碰到mysql的login log表越来越大,之前mysql的实现方式太慢了
业精于勤,荒于嬉;行成于思,毁于随。
如果你不需要记录用户登陆的历史详情,只是想要限制登陆次数就非常简单
为每个用户创建一个特别的key(举个例子,user_login_count_${用户ID}
每次登陆的时候拿到用户名,就去memcache去取这个key的value,如果发现其值已经超过12,则在此时报错说明只能尝试12次
如果不存在这个key,那么通过set新建,并把值记为1,expire时间设置为3600秒
如果登录失败,那么对这个key对应的value进行increment的操作,并重新设置超时时间为3600秒
如果登陆成功,则直接清除这个key的内容
因为 @vimac 的答案没有解决最近一小时问题,以下仅提供个思路,细节还可以完善
<?php // 存储失败次数时间戳 $key = "user:{$user_id}:login_failed"; $login_failed = $mem->get($key) or array(); $allow_times = 12; if(! checkAllowTimes($login_failed, $allow_times)){ throw new Exception("allow times max", 1); } if(! passValid($user_id, $password)){ array_unshift($login_failed, time()); // 最多存 12 条记录 if(count($login_failed) > $allow_times){ $login_failed = array_slice($login_failed, 0, $allow_times); } $mem->set($key, $login_failed, 3600); }else{ // 登录成功删除失败记录,取决于是连续失败还是累计失败? $mem->delete($key); // ... } function passValid($user_id, $password){ // ... // 伪代码 return true or false; } function checkAllowTimes($login_failed, $allow_times){ $last_hour = strtotime('1 hours ago'); for($i = 0; $i < count($login_failed); $i++){ // 如果已经登录失败 12 次 if($i >= $allow_times - 1){ return false; } // 1 小时前的登录记录不检索 if($login_failed[$i] <= $last_hour){ return true; } } return true; }
如果你不需要记录用户登陆的历史详情,只是想要限制登陆次数就非常简单
为每个用户创建一个特别的key(举个例子,user_login_count_${用户ID}
每次登陆的时候拿到用户名,就去memcache去取这个key的value,如果发现其值已经超过12,则在此时报错说明只能尝试12次
如果不存在这个key,那么通过set新建,并把值记为1,expire时间设置为3600秒
如果登录失败,那么对这个key对应的value进行increment的操作,并重新设置超时时间为3600秒
如果登陆成功,则直接清除这个key的内容
因为 @vimac 的答案没有解决最近一小时问题,以下仅提供个思路,细节还可以完善