2012-10-01 15 views
9

È possibile attivare il middleware rack solo su percorsi specifici di Rails?middleware Trigger Rack su percorsi Rails specifici

Ad esempio, supponiamo di voler eseguire un middleware del limitatore di velocità solo sullo spazio dei nomi API.

namespace :api do 
    resources :users 
end 

risposta

15

Ho avuto un buon successo con Rack::Throttle per limitazione della velocità. Sottoclassi una delle classi di acceleratore integrate e sovraccarichi il metodo allowed?. La logica personalizzata può controllare a quale controller è stato effettuato l'accesso e applicare il limite di velocità secondo necessità.

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

aggiunta alla risposta di Ian, per impostare l'ApiThrottle è necessario:

# 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 

Una cosa importante da aggiungere è che, per me, la path_info[:controller] venuto come "api/v1/cities" e non solo come "api". Ovviamente, ciò è dovuto alla configurazione dello spazio dei nomi. Pertanto, fare attenzione quando si imposta il throttler.

0

È possibile anche (ora) usare un motore di Rails per creare un set isolato di percorsi che aggiunge ulteriore middleware per lo stack per i suoi circuiti montati.

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

(Purtroppo ho trovato questa domanda mentre guardando per vedere se ci fosse un modo più semplice per farlo. Scrivi middleware personalizzato per ogni middleware che ho voluto aggiungere sembra ancora più rotonda rispetto all'utilizzo a Rails :: Engine)

Problemi correlati