|
| 1 | +# RateLimitBundle |
| 2 | +This bundle provides an easy way to protect your project by limiting access to your controllers. |
| 3 | + |
| 4 | +## Install the bundle |
| 5 | +```bash |
| 6 | +composer require bedrock/rate-limit-bundle |
| 7 | +``` |
| 8 | + |
| 9 | +Update your _config/bundles.php_ file to add the bundle for all env |
| 10 | +```php |
| 11 | +<?php |
| 12 | + |
| 13 | +return [ |
| 14 | + ... |
| 15 | + Bedrock\Bundle\RateLimitBundle\RateLimitBundle::class => ['all' => true], |
| 16 | + ... |
| 17 | +]; |
| 18 | +``` |
| 19 | + |
| 20 | +### Configure the bundle |
| 21 | +Add the _config/packages/bedrock_rate_limit.yaml_ file with the following data. |
| 22 | +```yaml |
| 23 | +bedrock_rate_limit: |
| 24 | + limit: 25 # 1000 requests by default |
| 25 | + period: 600 # 60 seconds by default |
| 26 | + limit_by_route: true|false # false by default |
| 27 | + display_headers: true|false # false by default |
| 28 | +``` |
| 29 | +By default, the limitation is common to all routes annotated `@RateLimit()`. |
| 30 | +For example, if you keep the default configuration and you configure the `@RateLimit()` annotation in 2 routes. Limit will shared between this 2 routes, if user consume all authorized calls on the first route, the second route couldn't be called. |
| 31 | +If you swicth `limit_by_route` to true, users will be allowed to reach the limit on each route annotated. |
| 32 | + |
| 33 | +If you switch `display_headers` to true, 3 headers will be added `x-rate-limit`, `x-rate-limit-hits`, `x-rate-limit-untils` to your responses. This can be usefull to debug your limitations. |
| 34 | +`display_headers` is used to display a verbose return if limit is reached. |
| 35 | + |
| 36 | +### Configure your storage |
| 37 | +You must tell Symfony which storage implementation you want to use. |
| 38 | + |
| 39 | +Update your _config/services.yml_ like this: |
| 40 | + |
| 41 | +```yaml |
| 42 | + ... |
| 43 | + Bedrock\Bundle\RateLimitBundle\Storage\RateLimitStorageInterface: '@Bedrock\Bundle\RateLimitBundle\Storage\RateLimitInMemoryStorage' |
| 44 | + ... |
| 45 | +``` |
| 46 | + |
| 47 | +By default, only `RateLimitInMemory` is provided. But feel free to create your own by implementing `RateLimitStorageInterface` or `ManuallyResetableRateLimitStorageInterface`. |
| 48 | +If your database has a TTL system (like Redis), you can implement only `RateLimitStorageInterface`. Otherwhise you must implement also `ManuallyResetableRateLimitStorageInterface` to manually delete rate limit in your database. |
| 49 | + |
| 50 | +### Configure your modifiers |
| 51 | +Modifiers are a way to customize the rate limit. |
| 52 | + |
| 53 | +This bundle provides 2 modifiers: |
| 54 | +* `HttpMethodRateLimitModifier` limits the requests by `http_method`. |
| 55 | +* `RequestAttributeRateLimitModifier` limits the requests by attributes value (taken from the `$request->attributes` Symfony's bag). |
| 56 | + |
| 57 | +Update your _config/services.yml_ like this: |
| 58 | + |
| 59 | +```yaml |
| 60 | + ... |
| 61 | + Bedrock\Bundle\RateLimitBundle\RateLimitModifier\HttpMethodRateLimitModifier: |
| 62 | + tags: [ 'rate_limit.modifiers' ] |
| 63 | +
|
| 64 | + Bedrock\Bundle\RateLimitBundle\RateLimitModifier\RequestAttributeRateLimitModifier: |
| 65 | + arguments: |
| 66 | + $attributeName: 'myRequestAttribute' |
| 67 | + tags: [ 'rate_limit.modifiers' ] |
| 68 | + |
| 69 | + ... |
| 70 | +``` |
| 71 | + |
| 72 | +You can also create your own rate limit modifier by implementing `RateLimitModifierInterface` and tagging your service accordingly. |
| 73 | + |
| 74 | +### Configure your routes |
| 75 | +Add the `@RateLimit()` annotation to your controller methods (by default, the limit will be 1000 requests per minute). |
| 76 | +This annotation accepts parameters to customize the rate limit. The following example shows how to limit requests on a route at the rate of 10 requests max every 2 minutes. |
| 77 | +:warning: This customization only works if the `limit_by_route` parameter is `true` |
| 78 | + |
| 79 | +```php |
| 80 | +/** |
| 81 | +* @RateLimit( |
| 82 | +* limit=10, |
| 83 | +* period=120 |
| 84 | +* ) |
| 85 | +*/ |
| 86 | +``` |
0 commit comments