sunspikes/php-ratelimiter

PHP 的无框架速率限制器

v1.2.1 2017-11-08 11:08 UTC

This package is auto-updated.

Last update: 2024-09-02 09:06:57 UTC


README

PHP 的一个框架无关、灵活且高度可扩展的速率限制器。

SensioLabsInsight Scrutinizer Code Quality Code Coverage Code Climate Build Status Latest Stable Version License

安装

通过 Composer

最佳安装方式是通过 packagist,在您的项目 composer.json 的 require 中包含 sunspikes/php-ratelimiter

    "require": {
        "sunspikes/php-ratelimiter":  "dev-master"
    }

不使用 Composer

您也可以从 Github 下载,但未提供自动加载器,因此您需要使用自己的 PSR-4 兼容的自动加载器进行注册。

使用

概述

// 1. Make a rate limiter with limit 3 attempts in 10 minutes
$cacheAdapter = new DesarrollaCacheAdapter((new DesarrollaCacheFactory())->make());
$settings = new ElasticWindowSettings(3, 600);
$ratelimiter = new RateLimiter(new ThrottlerFactory($cacheAdapter), new HydratorFactory(), $settings);

// 2. Get a throttler for path /login 
$loginThrottler = $ratelimiter->get('/login');

// 3. Register a hit
$loginThrottler->hit()

// 4. Check if it reached the limit
if ($loginThrottler->check()) {
    // access permitted
} else {
    // access denied
}

// Or combine the steps 3 & 4
if ($loginThrottler->access()) {
    // access permitted
} else {
    // access denied
}

// To get the number of hits
print $loginThrottler->count(); // or count($throttler)

配置

默认情况下,PHP Ratelimiter 使用 desarolla2 缓存适配器,在 config/config.php 中提供的示例配置

您可以在 config.php 中配置驱动程序,例如,要使用 memcache,将驱动程序更改为 'memcache'

return [
    'default_ttl' => 3600,
    'driver'      => 'memcache',
    'memcache' => [
        //....
    ],
];

扩展

PHP Ratelimiter 高度可扩展,您可以通过实现 Sunspikes\Ratelimit\Cache\Adapter\CacheAdapterInterface 来拥有自定义适配器

例如,要使用 Doctrine 缓存适配器

class DoctrineCacheAdapter implements CacheAdapterInterface
{
    public function __construct($cache)
    {
        $this->cache = $cache;
    }
    
    // Implement the methods
}

// Build adapter using APC cache driver
$adapter = new DoctrineCacheAdapter(new \Doctrine\Common\Cache\ApcCache());

您还可以通过实现 Sunspikes\Ratelimit\Throttle\Hydrator\DataHydratorInterface 来拥有自定义加湿器

例如,要使用 Symfony 请求对象而不是自定义 URL 进行速率限制

class RequestHydrator implements DataHydratorInterface
{
    public function hydrate($data, $limit, $ttl)
    {
        // Make the key string
        $key = $data->getClientIp() . $data->getPathInfo();

        return new Data($key, $limit, $ttl);
    }
}

// Hydrate the request to Data object
$hydrator = new RequestHydrator();

然后装饰或扩展 HydratorFactory 以识别您的数据

use Hydrator\FactoryInterface;

class MyHydratorFactory implements FactoryInterface
{
    private $defaultFactory;

    public function __construct(FactoryInterface $defaultFactory)
    {
        $this->defaultFactory = $defaultFactory;
    }

    public function make($data)
    {
        if ($data instanceof Request) {
            return new RequestHydrator();
        }

        return $this->defaultFactory->make($data);
    }
}

节流器类型

弹性窗口

弹性窗口节流器将在 Y 秒内允许 X 请求。任何进一步的访问尝试都将被计算,但返回状态为 false。注意,窗口将在每次命中时扩展 Y 秒。这意味着在 Y 秒内不需要任何命中,计数器才会重置为 0。

请参阅 概述示例 了解实例化。

基于时间的节流器

以下所有节流器都使用时间函数,因此需要不同的工厂进行构建

$cacheAdapter = new DesarrollaCacheAdapter((new DesarrollaCacheFactory())->make());
$timeAdapter = new PhpTimeAdapter();

$throttlerFactory = new TimeAwareThrottlerFactory($cacheAdapter, $timeAdapter);
$hydratorFactory = new HydratorFactory();

//$settings = ...
$ratelimiter = new RateLimiter($throttlerFactory, $hydratorFactory, $settings);

固定窗口

固定窗口节流器将在第一个请求后的 Y 秒内允许 X 请求。任何进一步的访问尝试都将被计算,但返回状态为 false。窗口根本不会扩展。

// Make a rate limiter with limit 120 attempts per minute
$settings = new FixedWindowSettings(120, 60);

移动窗口

移动窗口节流器将在之前的 Y 秒内允许 X 请求。任何进一步的访问尝试都将被计算,但返回状态为 false。窗口永远不会超过 Y 秒。

// Make a rate limiter with limit 120 attempts per minute
$settings = new MovingWindowSettings(120, 60);

漏桶

漏桶节流器将允许 X 请求在时间 Y 中划分。

超过阈值 T(默认:0)的任何访问尝试将延迟 Y / (X - T)

access() 如果延迟则返回 false,hit() 将返回等待的毫秒数

注意:此节流器的超时时间以毫秒为单位,而其他节流器类型是秒!

// Make a rate limiter with limit 120 attempts per minute, start delaying after 30 requests
$settings = new LeakyBucketSettings(120, 60000, 30);

重试队列

重试队列封装了另一个节流器。当此节流器收到一个在内部节流器上失败的命中时,请求将被延迟,直到内部节流器再次有空闲容量。

// Make a leaky bucket ratelimiter which delays any overflow
$settings = new RetrialQueueSettings(new LeakyBucketSettings(120, 60000, 120));

作者

Krishnaprasad MG [@sunspikes]

贡献

请随时发送拉取请求。

许可证

这是一个开源软件,根据 MIT 许可证 许可。