僅在特定Rails路由上觸發Rack中間件是否可能?在特定Rails路由上觸發Rack中間件
例如,假設我只想在api命名空間上運行速率限制器中間件。
namespace :api do
resources :users
end
僅在特定Rails路由上觸發Rack中間件是否可能?在特定Rails路由上觸發Rack中間件
例如,假設我只想在api命名空間上運行速率限制器中間件。
namespace :api do
resources :users
end
我對Rack::Throttle限速取得了很好的成功。子類內置節氣門類別之一,並且過載allowed?
方法。您的自定義邏輯可以檢查正在訪問哪個控制器,並根據需要應用速率限制。
class ApiThrottle < Rack::Throttle::Hourly
##
# Returns `false` if the rate limit has been exceeded for the given
# `request`, or `true` otherwise.
#
# Rate limits are only imposed on the "api" controller
#
# @param [Rack::Request] request
# @return [Boolean]
def allowed?(request)
path_info = (Rails.application.routes.recognize_path request.url rescue {}) || {}
# Check if this route should be rate-limited
if path_info[:controller] == "api"
super
else
# other routes are not throttled, so we allow them
true
end
end
end
添加到伊恩的回答,設置了ApiThrottle你必須:
# application.rb
require 'rack/throttle'
class Application < Rails::Application
...
config.require "api_throttle"
# max 100 requests per hour per ip
config.middleware.use ApiThrottle, :max => 100
...
end
# /lib/api_throttle.rb
# Ian's code here
一次加重要的是,對我來說,path_info[:controller]
之際,"api/v1/cities"
,而不是僅僅作爲"api"
。當然,這是由於命名空間配置。因此,在設置調速器時要小心。
您還可以(現在)使用Rails引擎創建一組隔離的路由,以便爲堆棧的路由添加其他中間件到堆棧。
見https://stackoverflow.com/a/41515577/79079
(不幸的是,我發現了這個問題,同時想看看是否有任何簡單的方法來做到這一點。寫作,我想添加的每個中間件自定義中間件顯得更爲迂迴的比使用Rails :: Engine)