[英]Trigger Rack middleware on specific Rails routes
是否可以仅在特定的Rails路由上触发Rack中间件?
例如,假设我只想在api名称空间上运行限速器中间件。
namespace :api do
resources :users
end
我使用Rack :: Throttle进行了成功的速率限制。 子类化内置节气门类之一,并allowed?
重载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
要补充的一件事是,对我而言, path_info[:controller]
以"api/v1/cities"
,而不仅仅是以"api"
。 当然,这是由于名称空间配置所致。 因此,在安装节流阀时要小心。
您还可以(现在)使用Rails Engine创建一组隔离的路由,从而为堆栈中已安装的路由添加其他中间件。
参见https://stackoverflow.com/a/41515577/79079
(不幸的是,我在寻找是否有更简单的方法时发现了这个问题。为我想添加的每个中间件编写一个定制的中间件似乎比使用Rails :: Engine更复杂。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.