oaklabs/phalcon-throttler

PHP Phalcon 框架的速率限制器。

v0.2 2018-03-19 10:50 UTC

This package is not auto-updated.

Last update: 2024-09-29 04:49:31 UTC


README

License Latest Stable Version Latest Unstable Version Build Status

简介

Phalcon Throttler 是 PHP Phalcon 框架的速率限制器。

它提供了一个简单的接口来构建使用各种策略的速率限制器,以及一个开箱即用的 Redis 速率限制器。

需要 PHP 7.1+ 和 Phalcon 3.1.2+。

安装

可以通过 Composer 安装 Throttler,只需在您的 composer.json 中包含 "oaklabs/phalcon-throttler": "^0.1",然后运行 composer updatecomposer install

用法

速率限制

Phalcon Throttler 默认附带了 Redis 速率限制器。它使用 PhpRedis 与 Redis 服务器通信。

首先,我们需要一个 Redis 实例。我们可以在 Phalcon 依赖注入容器中添加一个 redis 服务,以便在创建 Redis 速率限制器实例时使用。

$di->setShared('redis', function () use ($config) {
    $redis = new \Redis();
    $redis->pconnect($config->redis->host, $config->redis->port);
    $redis->auth($config->redis->password);

    return $redis;
});

我们还可以在依赖注入容器中设置它

$di->setShared('throttler',function() use ($di) {
    return new OakLabs\PhalconThrottler\RedisThrottler($di->get('redis'), [
        'bucket_size'  => 20,
        'refill_time'  => 600, // 10m
        'refill_amount'  => 10
    ]);
});

第二个参数允许配置速率限制器的行为

  • bucket_size:参考时间段内允许的击中次数
  • refill_time:计数器完全或部分重置的时间量
  • refill_amount:每次 refill_time 过后重置的击中次数

现在您已经可以成功地限制用户了

$throttler = $this->getDI()->get('throttler');
$rateLimit = $throttler->consume($this->request->getClientAddress());

if ($rateLimit->isLimited()) {
    // Do something
}

策略

剩下的问题是:应该在哪个适当的位置执行检查?

当然没有唯一有效的答案,可以在几个位置使用。

在分发器中检查

一个好的策略是在 Phalcon 分发器生命周期中进行检查。

在依赖注入中,我们可以使用 Phalcon 事件管理器来监听分发器事件,并将其绑定到某些安全插件

$di->setShared('eventsManager',function() use ($di) {
    $eventsManager = new \Phalcon\Events\Manager();
    return $eventsManager;
});

$di->set('dispatcher', function () use ($di) {
    //Create an EventsManager
    $eventsManager = $di->getShared('eventsManager');

    $security = new \MyNamespace\Security();
    $eventsManager->attach('dispatch', $security);

    $dispatcher = new \Phalcon\Mvc\Dispatcher();
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
});

并将我们的速率限制器放入其中

<?php

namespace MyNamespace;

use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use OakLabs\PhalconThrottler\ThrottlerInterface;

class Security extends Plugin
{
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {
        /** @var ThrottlerInterface $throttler */
        $throttler = $this->getDI()->get('throttler');
        $rateLimit = $throttler->consume($this->request->getClientAddress());

        if ($rateLimit->isLimited()) {
            $dispatcher->forward(
                [
                    'namespace' => 'MyNamespace\Http',
                    'controller' => 'error',
                    'action' => 'ratelimited',
                    'params' => $rateLimit->toArray()
                ]
            );
        }
    }
}

最后,如果用户被速率限制,执行重定向。由 $rateLimit->toArray() 方法返回的信息包含

[
    'hits' => (int) // Number of hits in the reference period,
    'remaining' =>(int) // Remaining hits before getting rate limited,
    'period' => (int) // Reference period in seconds,
    'hits_per_period' => (int) // Allowed number of hits in the reference period,
    'warning' => (bool) // Whether a warning has been emitted,
    'limited' => (bool) // Whether the User is rate limited
]

贡献指南

Throttler 遵循 PSR-1、PSR-2 和 PSR-4 PHP 编码标准和语义版本。

欢迎提交拉取请求。

许可证

Throttler 是在 MIT 许可证条款下分发的免费软件。