bakaphp/phalcon-throttler

PHP Phalcon 框架的速率限制器。

v0.3.2 2019-04-04 21:55 UTC

This package is auto-updated.

Last update: 2024-09-29 04:14:41 UTC


README

License Latest Stable Version Latest Unstable Version Build Status

简介

Phalcon Throttler 是一个针对 PHP Phalcon 框架的速率限制器。

它提供了一个简单的接口,使用各种策略构建速率限制器,并且自带一个 Redis 速率限制器。

需要 PHP 7.1+ 和 Phalcon 3.1.2+。

安装

速率限制器可以通过 Composer 安装,只需在 composer.json 中包含 "bakaphp/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 Baka\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 Baka\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
]

贡献指南

速率限制器遵循 PSR-1、PSR-2 和 PSR-4 PHP 编码标准,以及语义版本。

欢迎提交拉取请求。

许可

速率限制器是免费软件,根据 MIT 许可证条款分发。