14

特定のRailsルートでのみRackミドルウェアをトリガーすることは可能ですか?

たとえば、API名前空間でのみレートリミッターミドルウェアを実行したいとします。

namespace :api do
  resources :users
end
4

3 に答える 3

14

レート制限のために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
于 2012-11-30T21:34:40.817 に答える
5

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"

于 2014-01-03T19:32:24.860 に答える
1

Rails Engine を使用して、マウントされたルートのスタックに追加のミドルウェアを追加する分離された一連のルートを作成することもできます。

https://stackoverflow.com/a/41515577/79079を参照してください

(残念ながら、もっと簡単な方法がないか探していたときに、この質問を見つけました。追加したいすべてのミドルウェアに対してカスタム ミドルウェアを作成することは、Rails::Engine を使用するよりもさらに遠回りに思えます)

于 2017-01-09T15:40:51.040 に答える