跳至内容 跳至搜索
方法
R

实例公共方法

rate_limit(to:, within:, by: -> { request.remote_ip }

将速率限制应用于所有操作,或通过 only:except: 正常 before_action 过滤器指定的那些操作。

允许的最大请求数由 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
# 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