特定のRailsルートでのみRackミドルウェアをトリガーすることは可能ですか?
たとえば、API名前空間でのみレートリミッターミドルウェアを実行したいとします。
namespace :api do
resources :users
end
特定のRailsルートでのみRackミドルウェアをトリガーすることは可能ですか?
たとえば、API名前空間でのみレートリミッターミドルウェアを実行したいとします。
namespace :api do
resources :users
end
レート制限のためにRack::Throttleを使用してうまくいきました。組み込みスロットル クラスの 1 つをサブクラス化し、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
Ian の回答に追加して、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
追加する重要なことの 1 つは、私にとって、 はとしてだけでなく としてpath_info[:controller]
来たということです。もちろん、これは名前空間の構成によるものです。したがって、スロットルをセットアップするときは注意してください。"api/v1/cities"
"api"
Rails Engine を使用して、マウントされたルートのスタックに追加のミドルウェアを追加する分離された一連のルートを作成することもできます。
https://stackoverflow.com/a/41515577/79079を参照してください
(残念ながら、もっと簡単な方法がないか探していたときに、この質問を見つけました。追加したいすべてのミドルウェアに対してカスタム ミドルウェアを作成することは、Rails::Engine を使用するよりもさらに遠回りに思えます)