qnvip-com/php-rate-limit-middleware

A PHP middleware package for rate limiting and IP filtering with CIDR support

Installs: 9

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/qnvip-com/php-rate-limit-middleware

1.3.0 2025-11-24 08:30 UTC

This package is not auto-updated.

Last update: 2025-11-24 08:32:06 UTC


README

一个用于请求频率限制和IP过滤的PHP中间件包。

功能特性

  • IP 白名单和黑名单(支持 IPv4/IPv6 网段)
  • 请求频率限制(基于 Redis)
  • 自动黑名单机制(可配置启用/禁用)
  • Redis 异常容错处理
  • 可配置的策略执行模式(阻止/非阻止)
  • 全面的策略节点日志记录
  • 中间件集成
  • 可自定义的日志处理器(支持 PSR-3 标准)
  • 请求数最大值跟踪记录到文件或Redis

版本

当前版本: 1.1.0

查看 CHANGELOG.md 了解详细的版本历史。

安装

使用Composer安装:

composer require php-rate-limit-middleware/php-rate-limit-middleware

Redis 扩展要求

如果要使用限流功能,需要安装 Redis 扩展:

Windows:

  1. 下载适合您PHP版本的 php_redis.dll
  2. 将其放置在 PHP 扩展目录中
  3. 在 php.ini 中添加: extension=php_redis.dll
  4. 重启 Web 服务器

Linux/macOS (使用 PECL):

pecl install redis

然后在 php.ini 中添加: extension=redis

使用 Composer 替代方案

如果不方便安装 PHP 扩展,可以使用 Composer 包作为替代:

composer require phpredis/phpredis

使用方法

<?php

use QnvipCom\PhpRateLimitMiddleware\Config\Config;
use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter;
use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware;

// 加载配置
$config = Config::load();

// 初始化Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 创建速率限制器实例(可选地指定键前缀)
$rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit');

// 创建中间件实例
$middleware = new FilterMiddleware($config, $rateLimiter);

// 在您的应用中使用中间件处理请求
$response = $middleware->handle($request, function($req) {
    // 处理实际业务逻辑
    return $next($req);
});

// 手动管理自动黑名单
if ($rateLimiter->isIpAutoBlacklisted('192.168.1.100')) {
    echo "IP 192.168.1.100 在自动黑名单中";
}

// 手动将IP从自动黑名单中移除
$rateLimiter->removeFromAutoBlacklist('192.168.1.100');

// 获取所有自动黑名单中的IP
$blacklistedIps = $rateLimiter->getAutoBlacklist();

在 Laravel 中使用自定义日志处理器

<?php

use QnvipCom\PhpRateLimitMiddleware\Config\Config;
use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter;
use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware;
use QnvipCom\PhpRateLimitMiddleware\Logger\LoggerInterface;

// 创建一个适配 Laravel 日志系统的日志处理器
class LaravelLogger implements LoggerInterface 
{
    private $logger;
    
    public function __construct(\Illuminate\Log\LogManager $logger) 
    {
        $this->logger = $logger;
    }
    
    public function emergency(string $message, array $context = []): void
    {
        $this->logger->emergency($message, $context);
    }
    
    public function alert(string $message, array $context = []): void
    {
        $this->logger->alert($message, $context);
    }
    
    public function critical(string $message, array $context = []): void
    {
        $this->logger->critical($message, $context);
    }
    
    public function error(string $message, array $context = []): void
    {
        $this->logger->error($message, $context);
    }
    
    public function warning(string $message, array $context = []): void
    {
        $this->logger->warning($message, $context);
    }
    
    public function notice(string $message, array $context = []): void
    {
        $this->logger->notice($message, $context);
    }
    
    public function info(string $message, array $context = []): void
    {
        $this->logger->info($message, $context);
    }
    
    public function debug(string $message, array $context = []): void
    {
        $this->logger->debug($message, $context);
    }
    
    public function log($level, string $message, array $context = []): void
    {
        $this->logger->log($level, $message, $context);
    }
}

// 加载配置
$config = Config::load();

// 初始化Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 创建自定义日志处理器
$logger = new LaravelLogger(app('log'));

// 创建速率限制器实例(可选地指定键前缀)
$rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit', $logger);

// 创建中间件实例
$middleware = new FilterMiddleware($config, $rateLimiter, $logger);

在 ThinkPHP5 中使用自定义日志处理器

<?php

use QnvipCom\PhpRateLimitMiddleware\Config\Config;
use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter;
use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware;
use QnvipCom\PhpRateLimitMiddleware\Logger\LoggerInterface;

// 创建一个适配 ThinkPHP5 日志系统的日志处理器
class ThinkPHPLogger implements LoggerInterface 
{
    public function emergency(string $message, array $context = []): void
    {
        \think\facade\Log::emergency($message, $context);
    }
    
    public function alert(string $message, array $context = []): void
    {
        \think\facade\Log::alert($message, $context);
    }
    
    public function critical(string $message, array $context = []): void
    {
        \think\facade\Log::critical($message, $context);
    }
    
    public function error(string $message, array $context = []): void
    {
        \think\facade\Log::error($message, $context);
    }
    
    public function warning(string $message, array $context = []): void
    {
        \think\facade\Log::warning($message, $context);
    }
    
    public function notice(string $message, array $context = []): void
    {
        \think\facade\Log::notice($message, $context);
    }
    
    public function info(string $message, array $context = []): void
    {
        \think\facade\Log::info($message, $context);
    }
    
    public function debug(string $message, array $context = []): void
    {
        \think\facade\Log::debug($message, $context);
    }
    
    public function log($level, string $message, array $context = []): void
    {
        \think\facade\Log::record($message, $level, $context);
    }
}

// 加载配置
$config = Config::load();

// 初始化Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 创建自定义日志处理器
$logger = new ThinkPHPLogger();

// 创建速率限制器实例(可选地指定键前缀)
$rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit', $logger);

// 创建中间件实例
$middleware = new FilterMiddleware($config, $rateLimiter, $logger);

配置说明

默认配置包含以下选项:

  • ip_whitelist: IP白名单列表(支持精确IP地址和CIDR网段格式,如:192.168.0.0/16,也支持IPv6)
  • ip_blacklist: IP黑名单列表(支持精确IP地址和CIDR网段格式,如:172.16.0.0/12,也支持IPv6)
  • rate_limit.limit: 时间窗口内最大请求数
  • rate_limit.duration: 时间窗口长度(秒)
  • auto_blacklist.threshold: 自动加入黑名单的请求阈值(每时间窗口内的请求数)
  • auto_blacklist.duration: 自动黑名单持续时间(秒)

您可以根据需要修改这些配置值。

自动黑名单配置

'auto_blacklist' => [
    'enabled' => true,     // 是否启用自动黑名单功能
    'threshold' => 100,    // 触发自动黑名单的阈值(每分钟请求数)
    'duration' => 3600,    // 自动黑名单持续时间(秒),默认1小时,设为0或负数表示永久
]

当某个 IP 在单位时间内的请求次数超过阈值时,会自动加入黑名单并在指定时间后自动解除。 若将 duration 设置为 0 或负数,则该 IP 会被永久列入黑名单,除非手动移除。

中间件行为配置

'middleware' => [
    'block_on_violation' => true,     // 是否在违反策略时阻止访问
    'log_policy_violations' => true,  // 是否记录策略违规日志
]

默认情况下,当检测到违反策略的行为时(如IP在黑名单中、触发限流、在自动黑名单中),系统会阻止访问并返回相应的错误码。 当设置为 false 时,系统只会记录违规行为但允许访问继续进行,这在某些测试或监控场景中非常有用。

限流器详细日志配置

'rate_limit' => [
    'limit' => 60,          // 最大请求次数
    'duration' => 60,       // 时间窗口(秒)
    'log_detailed' => true, // 是否记录详细日志
]

log_detailed 设置为 true 时,限流器会记录更详细的日志信息,包括请求计数、限制值等。

请求数最大值跟踪配置

'request_count_tracking' => [
    'enabled' => false,              // 是否启用请求数跟踪
    'storage' => 'file',             // 存储方式: 'file' 或 'redis'
    'max_count_file' => '',          // 存储最大请求数的文件路径 (当storage为'file'时使用)
    'max_count_redis_key' => ''      // 存储最大请求数的Redis键 (当storage为'redis'时使用)
]

当启用请求数跟踪功能时,系统会将每个时间窗口内的最大请求数记录到指定的存储中(文件或Redis)。 这有助于监控系统负载和峰值流量。

策略节点日志说明

系统会在以下关键节点记录日志:

  1. 请求开始处理时记录客户端IP
  2. IP白名单检查结果
  3. IP黑名单检查结果
  4. 自动黑名单检查结果
  5. 请求频率限制检查结果
  6. 最终处理结果(允许/拒绝)

默认情况下,日志通过 PHP 的 error_log 函数记录,可以通过配置 PHP 的 error_log 指令将日志输出到指定文件。 如果提供了自定义的日志处理器,则会使用该处理器记录日志。

Redis 异常处理

当 Redis 出现连接异常或其他错误时,系统会记录错误日志但不会中断正常业务流程:

  • IP 白名单/黑名单检查不受影响
  • 请求频率限制会暂时跳过,允许请求通过
  • 自动黑名单检查会暂时跳过,允许请求通过
  • 所有 Redis 操作都有异常捕获,确保服务持续可用

运行测试

要运行测试,需要先安装开发依赖:

composer install

然后可以通过以下方式运行测试:

使用 PHPUnit 直接运行

./vendor/bin/phpunit

使用 Composer 脚本运行

composer test

在 Windows 系统上运行

test.bat

在 Unix/Linux/macOS 系统上运行

./test.sh

运行特定测试类

./vendor/bin/phpunit tests/RateLimit/RateLimiterTest.php
./vendor/bin/phpunit tests/Middleware/FilterMiddlewareTest.php
./vendor/bin/phpunit tests/Middleware/IpMatchingTest.php
./vendor/bin/phpunit tests/Middleware/AutoBlacklistTest.php

注意:测试需要 Redis 服务器运行在本地默认端口(6379)上。

发布

要发布新版本,请更新以下文件:

  1. composer.json 中的版本号
  2. CHANGELOG.md 中的变更记录
  3. 使用 Git tag 标记新版本

许可证

本项目采用 MIT 许可证授权。