如何限制登录尝试-PHP& MySQL和CodeIgniter [英] How to throttle login attempts - PHP & MySQL & CodeIgniter

查看:67
本文介绍了如何限制登录尝试-PHP& MySQL和CodeIgniter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够基于失败的尝试来限制登录尝试,但是我遇到了一些问题.

I'd like to be able to throttle login attempts based on failed attempts but I got some questions.

我应该使用MySQL吗? (读到它可能会使数据库紧张)
我应该在整个系统范围内还是每个系统范围内限制每个用户? (以防止普通人猜测密码)
我应该如何计算我的门槛? (因此它会自动适应变化/增长)
我应该如何检索该阈值?查询/计算每个失败或存储在缓存中?
我应该用什么来节流? (阅读有关sleep()可能最终使服务器紧张的响应)

Should I use MySQL? (read that it could strain the DB)
Should I throttle per user and system-wide or just system-wide? (so to stop normal people from guessing passwords)
How should I calculate my threshold? (so it automatically adapts to changes/growth)
How should I retrieve this threshold? Query/calculate on every fail or store on cache?
What should I use to throttle? (read a response that sleep() could end up straining the server)

有人有一些示例代码吗?

Does anybody have some sample code?

我对此很陌生,因此感谢您的帮助! 谢谢

I'm quite new at this so I appreciate the help! Thanks

推荐答案

我实现了 phunction 中的noreferrer>穷人节流机制单独使用APC,这就是我的用法:

I implemented a poor-man's throttling mechanism in phunction using APC alone, this is how I use it:

// 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上使用它,并将值传递给我的路由方法,但这是另一回事了.

I use this on my Front-Controller and pass the value to my routing method, but that's another story.

最重要的是,如果您使用APC,则由于APC遵循FILO方法,因此可以使事情在内存中保持非常快的速度,并且几乎不占用内存.如果您需要更高的超时时间,则可以考虑使用不是基于内存的内容.

The bottom line is that if you use APC you're able to keep things very fast in memory and with little memory consumption because APC follows a FILO methodology. If you need way higher timeouts you may consider using something that's not memory based though.

顺便说一句:MySQL支持带有MEMORY引擎的表.

BTW: MySQL supports tables with the MEMORY engine.

sleep()的问题:

The problem with sleep():

安装了PHP作为模块的典型Apache Web服务器每个实例将占用大约10 MB的RAM,为避免超出可用内存,可以配置一些Apache设置以限制Apache能够支持的最大实例数开始.

A typical Apache web server with PHP installed as a module will eat about 10 MB of RAM per instance, to avoid exceeding your available ram there are some Apache settings that you can configure to limit the maximum number of instances that Apache is able to start.

问题是,当您sleep()时,该实例仍然处于活动状态,并且具有足够的请求,最终可能会占用所有可用的插槽来启动新服务器,从而使您的网站无法访问,直到一些未完成的请求完成.

The problem is when you sleep(), that instance is still active and with enough requests could end up eating all the available slots to start new servers, thus rendering your web site inaccessible until some pending requests are completed.

PHP AFAIK无法克服这个问题,因此最终取决于您.

There is no way to overcome this from PHP AFAIK, so in the end it's up to you.

系统范围内的节流原理相同:

The principle is the same for system wide throttling:

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;
}

这篇关于如何限制登录尝试-PHP&amp; MySQL和CodeIgniter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆