如何使 Rack::Attack 在负载均衡器后面工作?

Kev*_*nce 3 ruby-on-rails rackattack

我使用了 Rack::Attack 的示例节流代码。

throttle('req/ip', limit: 100, period: 5.minutes) do |req|
  req.ip unless req.path.starts_with?('/assets')
end
Run Code Online (Sandbox Code Playgroud)

这在我们的临时服务器上效果很好,但立即遇到了生产限制,因为 req.ip 返回我们的负载均衡器的 IP 地址,而不是客户端的 remote_ip。

请注意,remote_ip 是 ActionDispatch::Request 中的方法,而不是 Rack::Attack::Request 中的方法。

我们在 Ruby 2.2 上使用 Rails 3.2.2。

Kev*_*nce 5

我可以通过向 Rack::Attack::Request 添加方法来使其工作

class Rack::Attack
  class Request < ::Rack::Request
    def remote_ip
      @remote_ip ||= (env['action_dispatch.remote_ip'] || ip).to_s
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后使用

req.remote_ip unless req.path.starts_with?('/assets')
Run Code Online (Sandbox Code Playgroud)