модуль ActionController::RateLimiting::ClassMethods
Публичные методы экземпляра
# File actionpack/lib/action_controller/metal/rate_limiting.rb, line 66
def rate_limit(to:, within:, by: -> { request.remote_ip }, with: -> { raise TooManyRequests }, store: cache_store, name: nil, scope: nil, **options)
before_action -> { rate_limiting(to: to, within: within, by: by, with: with, store: store, name: name, scope: scope || controller_path) }, **options
end Применяет ограничение частоты запросов ко всем действиям или к действиям, указанным с помощью обычных фильтров before_action с параметрами only: и except:.
Максимальное допустимое число запросов задаётся to: и ограничивается временным интервалом, заданным within:.
По умолчанию ограничения частоты запросов применяются отдельно для каждого IP-адреса, с которого отправляется запрос, но вы можете передать собственную функцию идентификации, указав вызываемый объект в параметре by:. Она выполняется в контексте контроллера, обрабатывающего запрос.
По умолчанию ограничения частоты запросов привязаны к пути контроллера. Если вы хотите использовать общие ограничения для нескольких контроллеров, можно задать собственную область действия, передав значение в параметре scope:.
Превышение ограничения частоты запросов приведёт к ошибке ActionController::TooManyRequests. По умолчанию Action Dispatch перехватывает эту ошибку и отклоняет запрос, возвращая ответ 429 Too Many Requests. Вы можете настроить это поведение, передав вызываемый объект в параметре with:. Он выполняется в контексте контроллера, обрабатывающего запрос.
Для ограничения частоты запросов требуется базовое ActiveSupport::Cache хранилище; по умолчанию используется config.action_controller.cache_store, которое, в свою очередь, по умолчанию использует глобальное config.cache_store. Если вы не хотите хранить данные об ограничениях частоты запросов в том же хранилище, что и обычный кэш, можно передать пользовательское хранилище в параметре store.
Чтобы использовать несколько ограничений частоты запросов для одного контроллера, каждому из них нужно явно задать имя с помощью параметра name:.
Примеры:
class SessionsController < ApplicationController
rate_limit to: 10, within: 3.minutes, only: :create
end
class SignupsController < ApplicationController
rate_limit to: 1000, within: 10.seconds,
by: -> { request.domain }, with: :redirect_to_busy, only: :new
private
def redirect_to_busy
redirect_to busy_controller_url, alert: "Too many signups on domain!"
end
end
class APIController < ApplicationController
RATE_LIMIT_STORE = ActiveSupport::Cache::RedisCacheStore.new(url: ENV["REDIS_URL"])
rate_limit to: 10, within: 3.minutes, store: RATE_LIMIT_STORE
rate_limit to: 100, within: 5.minutes, scope: :api_global
end
class SessionsController < ApplicationController
rate_limit to: 3, within: 2.seconds, name: "short-term"
rate_limit to: 10, within: 5.minutes, name: "long-term"
end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.