bedrockstreaming / rate-limit-bundle
管理您路由的速率限制
Requires
- php: >=8.0
- ext-json: *
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/event-dispatcher: ^5.4 || ^6.0
- symfony/http-foundation: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/options-resolver: ^5.4 || ^6.0
Requires (Dev)
- m6web/php-cs-fixer-config: ^2.1
- phpstan/phpstan: ^1.5
- phpstan/phpstan-phpunit: ^1.1
- phpunit/phpunit: 9.5.*
- rector/rector: ^0.12.22
- symfony/var-dumper: ^5.4 || ^6.0
Suggests
- webonyx/graphql-php: Needed to support @GraphQLRateLimit attribute
README
此包提供了一种简单的方法,通过限制对控制器的访问来保护您的项目。
安装包
composer require bedrockstreaming/rate-limit-bundle
更新您的 config/bundles.php 文件以添加所有环境下的包
<?php return [ ... Bedrock\Bundle\RateLimitBundle\RateLimitBundle::class => ['all' => true], ... ];
配置包
添加 config/packages/bedrock_rate_limit.yaml 文件,包含以下数据。
bedrock_rate_limit: limit: 25 # 1000 requests by default period: 600 # 60 seconds by default limit_by_route: true|false # false by default display_headers: true|false # false by default
默认情况下,限制适用于所有标记了 #[RateLimit]
的路由。例如,如果您保留默认配置并在2个路由中配置了 #[RateLimit]
属性,则限制将在这两个路由之间共享,如果用户在第一个路由上消耗了所有授权调用,则第二个路由将无法被调用。如果将 limit_by_route
设置为 true,则允许用户在每个标记的路由上达到限制。
#[GraphQLRateLimit]
属性允许您通过 GraphQL 查询或突变进行速率限制。/!\ 使用此属性,您需要安装建议的包。
如果将 display_headers
设置为 true,则会在您的响应中添加3个头 x-rate-limit
、x-rate-limit-hits
、x-rate-limit-untils
。这可以用于调试限制。 display_headers
用于在达到限制时显示详细返回。
配置您的存储
您必须告诉 Symfony 您想要使用哪种存储实现。
更新您的 config/services.yml 文件如下
... Bedrock\Bundle\RateLimitBundle\Storage\RateLimitStorageInterface: '@Bedrock\Bundle\RateLimitBundle\Storage\RateLimitInMemoryStorage' ...
默认情况下,只提供了 RateLimitInMemory
。但您可以自由创建自己的,通过实现 RateLimitStorageInterface
或 ManuallyResetableRateLimitStorageInterface
。如果您的数据库具有 TTL 系统(如 Redis),则只需实现 RateLimitStorageInterface
。否则,您必须实现 ManuallyResetableRateLimitStorageInterface
以在数据库中手动删除速率限制。
配置您的修改器
修改器是一种自定义速率限制的方式。
此包提供了2个修改器
HttpMethodRateLimitModifier
通过http_method
限制请求。RequestAttributeRateLimitModifier
通过属性值(从 Symfony 的$request->attributes
包中获取)限制请求。
更新您的 config/services.yml 文件如下
... Bedrock\Bundle\RateLimitBundle\RateLimitModifier\HttpMethodRateLimitModifier: tags: [ 'rate_limit.modifiers' ] Bedrock\Bundle\RateLimitBundle\RateLimitModifier\RequestAttributeRateLimitModifier: arguments: $attributeName: 'myRequestAttribute' tags: [ 'rate_limit.modifiers' ] ...
您也可以通过实现 RateLimitModifierInterface
并相应标记您的服务来创建自己的速率限制修改器。
配置您的路由
带有属性
将 #[RateLimit]
属性添加到您的控制器方法中(默认情况下,限制为每分钟1000个请求)。此属性接受参数以自定义速率限制。以下示例显示了如何以每2分钟最多10个请求的速率限制路由上的请求:警告:此自定义仅当 limit_by_route
参数为 true
时有效
#[RateLimit(limit: 10, period: 120)]
要限制您的 GraphQL API,请将 #[GraphQlRateLimit]
属性添加到您的 GraphQL 控制器中。此属性需要端点列表,并接受参数以自定义速率限制。以下示例显示了如何以每2分钟最多10个请求的速率限制端点上的请求,并使用默认限制。
#[GraphQlRateLimit( endpoints: [ [ 'endpoint' => 'GetMyQuery', 'limit' => 10, 'period' => 12], [ 'endpoint' => 'EditMyMutation'], ] )]
在 YAML 中
您还可以通过路由名称在配置文件(Yaml)中添加速率限制。如果为路由未定义 period
或 limit
,则包将采用通用选项。
bedrock_rate_limit: limit: 1000 period: 60 routes: get_foobar: limit: 500 period: 10 post_foobar: period: 10
迁移到 php8
如果您使用 rector,则可以使用这些规则自动将注释迁移到属性
$rectorConfig->ruleWithConfiguration( \Rector\Php80\Rector\Class_\AnnotationToAttributeRector::class, [ new \Rector\Php80\ValueObject\AnnotationToAttribute( 'Bedrock\Bundle\RateLimitBundle\Annotation\GraphQLRateLimit', \Bedrock\Bundle\RateLimitBundle\Attribute\GraphQLRateLimit::class ), new \Rector\Php80\ValueObject\AnnotationToAttribute( 'Bedrock\Bundle\RateLimitBundle\Annotation\RateLimit', \Bedrock\Bundle\RateLimitBundle\Attribute\RateLimit::class ) ], );