bakaphp / phalcon-throttler
PHP Phalcon 框架的速率限制器。
Requires
- php: >=7.1
- ext-phalcon: >=3.1.2
Requires (Dev)
- phalcon/incubator: dev-master
- phpunit/phpunit: ^5.7
README
简介
Phalcon Throttler 是一个针对 PHP Phalcon 框架的速率限制器。
它提供了一个简单的接口,使用各种策略构建速率限制器,并且自带一个 Redis 速率限制器。
需要 PHP 7.1+ 和 Phalcon 3.1.2+。
安装
速率限制器可以通过 Composer 安装,只需在 composer.json 中包含 "bakaphp/phalcon-throttler": "^0.1"
,然后运行 composer update
或 composer 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 许可证条款分发。