Регулирование POST-запросов в приложении rails - PullRequest
5 голосов
/ 12 марта 2012

Я использую rack-throttle в качестве двигателя ограничения скорости в моем приложении rails 3. Я создал свой собственный класс на основе Rack::Throttle::Interval для определения пользовательской логики ограничения скорости. Я проверяю, сделан ли запрос на точный контроллер и точное действие. Это прекрасно работает, если я сделаю GET запрос. Однако, если я отправлю запрос POST, у меня возникнут некоторые проблемы.

class CustomLimiter < Rack::Throttle::Interval
  def allowed?(request)
    path_info = Rails.application.routes.recognize_path request.url rescue path_info = {} 
    if path_info[:controller] == "some_controller" and path_info[:action] == "some_action"
      super
    else
      true
    end
  end
end

Вот мои действия контроллера

def question
  #user is redirected here
end

def check_answer
  #some logic to check answer
  redirect_to question_path
end

Мои маршруты

get "questions" => "application#question", :as => "question"
post "check_answer" => "application#check_answer", :as => "check_answer"

EDIT:

Проблема в том, что POST запросы поступают в приложение, поэтому вызывается метод allowed?. Но когда я звоню Rails.application.routes.recognize_path, я получаю Route set not finalized исключение. Как я могу запретить пользователю отправлять много почтовых запросов о точном действии точного контроллера с помощью rack-throttle

Промежуточное программное обеспечение добавлено в application.rb

class Application < Rails::Application
  #Set up rate limiting
  config.require "ip_limiter"
  config.require "ip_user_agent_limiter"
  config.middleware.use IpLimiter, :min => 0.2
  config.middleware.use IpUserAgentLimiter, :min => 2
end

И IpLimiter, и IpUserAgentLimiter являются производными от пользовательского ограничителя

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

После прочтения кода Rails.application.routes.recognize_path (http://apidock.com/rails/ActionDispatch/Routing/RouteSet/recognize_path) этот метод получает второй аргумент, в котором вы можете передать МЕТОД.

Попробуйте с:

path_info = Rails.application.routes.recognize_path(request.url, {:method => request.request_method}) rescue path_info = {} 

После того, как все методы могут работать, я полагаю.

0 голосов
/ 04 декабря 2013

Этот работал для меня, чтобы перехватить все запросы POST и игнорировать все запросы GET:

class CustomLimiter < Rack::Throttle::Interval

  def allowed?(request)
    return true unless request.request_method == "POST"
    super request
  end

end
...