Rate Limiter
The rate limiter is responsible for limiting the rate of requests a user can make to the application within a given time period. This is useful for preventing a user from spamming the application, but mainly to control the amount of requests a user is allowed to make. The rate limiter is configured in the etc/config/security.yaml
file.
Rate limits are measured using a token bucket algorithm. The limit is the maximum number of tokens that can be stored in the bucket. The period is the time in seconds that the bucket is allowed to hold tokens. The strategy is the algorithm used to determine the number of tokens that are added to the bucket.
#
Default Rate LimiterThe default rate limiter limits all incoming requests as configured. The Swift\Security\RateLimiter\Kernel\Middleware\RateLimitingMiddleware
middleware is responsible for adding the default rate limiter to the request. The default_limit, default_period and default_strategy are configured in the etc/config/security.yaml
file. Default rate limiter is disabled by default. To enable it, set default_enabled: true
in the rate_limit
section.
By default, each request consumes one token.
#
GraphQL Rate LimiterGraphQl requests consume at least one token, however this is calculated based on the complexity of the query. The complexity of the query is determined by the number of fields in the query divided by 100. For example, a query with 100 fields will consume 1 token. A query with 200 fields will consume 2 tokens. The minimum is 1 token. A query with 170 fields, will consume 2 tokens (170 / 100 = 1.7). This will round off at 2 tokens.
#
Custom Rate LimiterThere's a dozen of reasons to use a custom rate limiter. The most common is to limit the rate of requests to a specific endpoint, or you might want to limit the rate of requests to a specific user. You can still combine this with the default rate limiter. An example of this is Login throttling.
#
ConfigurationThe easiest way to configure a custom rate limiter is to add a new rate to the rates
array in the rate_limit
section of the etc/config/security.yaml
file.
The RateLimiterFactory will now look for a rate with the name foo_bar
and return a RateLimiter configured as such.
#
Rate Limiter Configuration FactoryThe RateLimiterConfigurationFactory is responsible for creating RateLimiterConfigurationInterface instances. These represent the configuration for a rate limiter.
#
ExampleThis example shows how Swift uses the RateLimiterConfigurationFactory to create a RateLimiterConfigurationInterface instance for the custom configured rate limiter through configuration.
#
Rate Limiter FactoryThe RateLimiterFactory is responsible for creating RateLimiterInterface instances based on the RateLimiterConfigurationInterface.
#
ExampleThis example shows how Swift uses the RateLimiterFactory to create a RateLimiterInterface instance.
#
Token storageThe TokenStorage is responsible for storing and fetching token buckets. By default, the TokenStorage is a DatabaseTokenStorage, but a custom TokenStorage can be used.
#
Example#
StrategyThe Strategy is responsible for calculating the number of tokens to consume. The default strategy is the SlidingWindowStrategy. A custom strategy can be used by implementing the Swift\Security\RateLimiter\RateLimiterInterface
. And defining a factory for initializing the strategy, like the CoreStrategyFactory above.
#
StrategyStrategies are responsible for calculating the number of tokens over a period of time. The default strategy is the SlidingWindowStrategy. This is the strategy that Swift uses by default and is the most common strategy. However, you can create your own strategy and use it by implementing the Swift\Security\RateLimiter\RateLimiterInterface
. An example of another strategy is the FixedWindowStrategy.
#
Sliding windowThe SlidingWindowStrategy calculated the number of available tokens based on how many tokens were consumed between the moment of the request and the moment of the request minus the interval.
For example, if a request is made at time t
and the interval is 1 minute
. The strategy will fetch all tokens created between t - 1 minute
and t
. It will now withdraw those tokens from the limit and return the number of tokens that can still be consumed.
#
UsageInteraction with the Rate Limiter is done through the Swift\Security\RateLimiter\RateLimiterFactory
. The RateLimiterFactory is responsible for creating RateLimiterInterface instances.
#
Example of usage in middleware#
Example of usage in EventSubscriber#
Rate Limiter HTTP HeadersIt is good practice to add the rate limiter headers to the response. This is easily done by using the RateLimiter::bindToResponse method. Like in the example above, the RateLimiter::bindToResponse method will add the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers to the response.