2012-10-01 11 views
9

Czy jest możliwe wyzwolenie oprogramowania pośredniczącego Rack tylko na określonych trasach Railsowych?Trigger Rack middleware na określonych trasach Railsowych

Załóżmy na przykład, że chciałbym uruchomić oprogramowanie pośredniczące z ogranicznikiem szybkości tylko w przestrzeni nazw api.

namespace :api do 
    resources :users 
end 

Odpowiedz

15

Miałem dobry sukces z Rack::Throttle dla ograniczenia stawki. Podklasuj jedną z wbudowanych klas przepustnicy i przeładuj metodę allowed?. Twoja niestandardowa logika może sprawdzić, który kontroler jest dostępny, i zastosować limit szybkości w razie potrzeby.

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 
5

Dodawanie do odpowiedzi Iana, aby ustawić się na ApiThrottle trzeba:

# 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 

Jedną ważną rzeczą, aby dodać to, że dla mnie, path_info[:controller] przyszedł jako "api/v1/cities" a nie tylko jako "api". Oczywiście wynika to z konfiguracji przestrzeni nazw. Dlatego należy zachować ostrożność podczas ustawiania dławika.

0

Możesz także (teraz) użyć mechanizmu Railsowego do utworzenia izolowanego zestawu tras, który dodaje dodatkowe oprogramowanie pośrednie do stosu dla tras zamontowanych.

Zobacz https://stackoverflow.com/a/41515577/79079

(Niestety znalazłem na to pytanie, patrząc, czy nie było żadnych prostszy sposób to zrobić. Pisanie własnego middleware dla każdej warstwy pośredniej, które chciałem dodać wydaje się jeszcze bardziej okrągłe o niż przy użyciu a Rails :: Engine)

Powiązane problemy