-
Notifications
You must be signed in to change notification settings - Fork 337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Throttle does not read params when posted as Json #122
Comments
Rails has extra Rack middleware for parsing JSON params that is below Rack::Attack in the stack. (i.e. JSON params are parsed after being processed by Rack::Attack). ActionDispatch in Rails does the parsing with this middleware class: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/params_parser.rb#L31 There should be a way to move the middleware around so that the params parser will be higher in the stack than Rack::Attack, but that's not something I've tried. This guide should at least point you in the right direction: http://edgeguides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack |
That makes sense. This is the order of my stack: I think the best method would be to move the Rack::Attack up, instead of moving the ActionDispatch |
I moved RackAttack to after the ActionDispatch::ParamsParser: |
Hmmm. I don't know what's going wrong, but it seems like this issue is outside the scope of Rack::Attack. (Unless the problem is from changing You could probably get a more helpful answer over at the main Rails project where they maintain ActionDispatch's middleware: https://github.com/rails/rails (Worst case scenario, I'd recommend extending Rack::Attack::Request to implement a |
Thank you, are there any examples that you know of, of extending Rack::Attack::Request? |
There's an example in the gem source code here https://github.com/kickstarter/rack-attack/blob/master/lib/rack/attack/request.rb and it's also discussed in issues #73 and #113. If you're wondering where to put the monkey-patch, I like this organizational approach: http://stackoverflow.com/questions/3420680/monkey-patching-in-rails-3 |
When trying your suggestion, I found the params: Rack::Attack.throttle('logins', :limit => 3, :period => 60.seconds) do |req| This works perfectly, I did not do the monkey-patch, all I did was make sure that Rack::Attack loads after the ActionDispatch::ParamsParser: in application.rb |
Ah, glad to hear everything's working for you now 👍 Please feel free to close this issue :) |
Sure, thanks for your help. |
In Rails 5 there is no This is what I use now, but I'm not totally satisfied: Rack::Attack.throttle('login', limit: 6, period: 60.seconds) do |req|
begin
# req.params for JSON is not yet available at this step
JSON.parse(req.body.string)['email'] if req.path == '/login' && req.post?
rescue JSON::ParserError => e
end
end Does anybody have an idea how to achieve this by not parsing the JSON manually? |
Thanks @peterfication for your solution. I'm using PhusionPassenger and discovered that I needed to call throttle("logins/email", limit: 5, period: 30.seconds) do |req|
begin
email = JSON.parse(req.body.read())['email']
req.body.rewind
email if req.path == '/api/v2/authenticate' && req.post?
rescue JSON::ParserError => e
end
end |
Just FYI for anyone reading this now. I think the recommended way that avoid the read/rewind problem, etc...would be to do the solution found here: real_req = ActionDispatch::Request.new(req.env) |
In my application we have an authentication POST call which contains a json in the body.
{"session": {"email":"[email protected], "password":"*****"}}
My rack attack config contains the following throttle:
Rack::Attack.throttle('logins', :limit => 3, :period => 60.seconds) do |req|
req.params['session']['email'] if req.path == '/login' && req.post?
end
The issue is that req.params is nil, I also have application/json as content-type, this works within the app just fine, but for some reason it is not parsed or picked up here. Now if I include fields in the query string or as non json parameters in the body, it works. What can be updated in order for this to work properly?
The text was updated successfully, but these errors were encountered: