php - 如何限制登录尝试 - PHP & MySQL & CodeIgniter

标签 php mysql security authentication throttling

我希望能够根据失败的尝试限制登录尝试,但我有一些问题。

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

有没有人有一些示例代码?

我在这方面很陌生,所以非常感谢您的帮助! 谢谢

最佳答案

我实现了一个 poor-man's throttling mechanismphunction单独使用 APC,这就是我的使用方式:

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

我在我的前端 Controller 上使用它并将值传递给我的路由方法,但那是另一回事了。

底线是,如果您使用 APC,您可以在内存中保持非常快的速度并且内存消耗很少,因为 APC 遵循 FILO 方法。如果您需要更高的超时时间,您可以考虑使用不基于内存的东西。

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


sleep() 的问题:

将 PHP 作为模块安装的典型 Apache Web 服务器每个实例将消耗大约 10 MB 的 RAM,为避免超过可用 ram,您可以配置一些 Apache 设置来限制 Apache 能够运行的最大实例数开始。

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

没有办法从 PHP AFAIK 中克服这个问题,所以最终取决于您。


系统级 throttle 的原理是一样的:

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 - 如何限制登录尝试 - PHP & MySQL & CodeIgniter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5037083/

相关文章:

mysql - SQL 语法错误 #1064 游标 (mysql)?

security - 大多数开放平台上的app-id和app-key有什么区别?

c# - 将 ASP.NET 连接到 SQL Server 的最佳实践

php - 如何在 php 中减去两个日期

php - 如何使用 PhpStorm 连接到 Openshift 数据库?

mysql - 如何使用 JOINED 表和 ORDER BY 和 OFFSET 改进 MySQL 查询

javascript - 动态添加输入字段并将数据保存到数据库

php - AWS S3 PHP API : How to get url after file upload?

php - 在我的类里面使用 pdo php

security - 如何追踪IE8安全警告的来源?