我希望能够根据失败的尝试来限制登录尝试,但我遇到了一些问题。
我应该使用MySQL吗? (读到它会使DB变形)
我应该对每个用户和系统范围进行限制还是只对整个系统进行限制? (这样可以阻止正常人猜测密码)
我应该如何计算我的门槛? (因此它会自动适应变化/增长)
我该如何检索此阈值?查询/计算缓存中的每个失败或存储?
我应该用什么节流? (读取睡眠()可能最终导致服务器紧张的响应)
有人有一些示例代码吗?
我是新手,所以我很感激你的帮助! 感谢
答案 0 :(得分:6)
我仅使用APC在poor-man's throttling mechanism中实现了phunction,这就是我使用它的方式:
// allow 60 requests every 30 seconds
// each request counts as 1 (expensive operations can use higher values)
// keep track of IPs by REMOTE_ADDR (ignore others)
$throttle = ph()->Throttle($ttl = 30, $exit = 60, $count = 1, $proxy = false);
if ($throttle === true)
{
// IP exceded 30 requests in the last 60 seconds, die() here
}
else
{
// $throttle is a float
// number of requests in the last 30 seconds / 30 seconds
/*
1 req / 30 = 0,033 sec
5 req / 30 = 0,166 sec
10 req / 30 = 0,333 sec
15 req / 30 = 0,5 sec
20 req / 30 = 0,666 sec
25 req / 30 = 0,833 sec
30 req / 30 = 1 sec
*/
usleep(intval(floatval($throttle) * 1000000));
}
我在我的Front-Controller上使用它并将值传递给我的路由方法,但这是另一个故事。
最重要的是,如果你使用APC,你可以在内存中保持非常快的速度,而且内存消耗很少,因为APC遵循FILO方法。如果你需要更高的超时时间,你可以考虑使用非基于内存的东西。
BTW:MySQL支持使用MEMORY引擎的表。
sleep()
的问题:
安装了PHP作为模块的典型Apache Web服务器每个实例将占用大约10 MB的RAM,为了避免超出可用的ram,可以配置一些Apache设置来限制Apache能够实现的最大实例数开始。
问题是当你sleep()
时,该实例仍处于活动状态并且有足够的请求可能最终会占用所有可用的插槽来启动新服务器,从而导致您的网站无法访问,直到某些待处理的请求完成为止。< / p>
没有办法从PHP AFAIK中克服这个问题,所以最终还是取决于你。
系统范围限制的原理相同:
function systemWide($ttl = 86400, $exit = 360)
{
if (extension_loaded('apc') === true)
{
$key = array(__FUNCTION__);
if (apc_exists(__FUNCTION__) !== true)
{
apc_store(__FUNCTION__, 0, $ttl);
}
$result = apc_inc(__FUNCTION__, 1);
if ($result < $exit)
{
return ($result / $ttl);
}
return true;
}
return false;
}
答案 1 :(得分:1)
在这样的表中记录失败的登录尝试:
FailedLogins
id
timestamp
ip
每次用户尝试登录时,都会检查用户的IP地址是否在过去的Y秒内有X次失败的登录尝试次数。
如果用户在Y秒内失败X次,则会显示错误消息或CAPTCHA。
答案 2 :(得分:0)
MySQL数据库能够处理请求/秒的音调,因此如果您没有数千名用户,则不必担心瓶颈。
你也可以使用sleep() 注意:PHP处理的用户多于ASP.NET - 所以再次。如果你没有成千上万的用户,你可以使用睡眠方法,没有瓶颈。
我通常这样做的方法是存储登录尝试(IP,用户ID和时间戳)。 将其存放在一张桌子中,并在您喜欢的时候重置桌子(在一定的大小或一天中的某个时间)。 如果用户ID + IP在“特定时间”内具有超过“登录尝试次数”,则将用户重定向到告知用户他/她已经习惯了多次尝试但无法登录的页面接下来的15分钟(或任何你想要的)。 像我猜的那样有点“Windows”,但它的作用就像一个魅力:)