diff --git a/README.md b/README.md index df4c87a..6ea8f5d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1321 TILs and counting..._ +_1322 TILs and counting..._ --- @@ -845,6 +845,7 @@ _1321 TILs and counting..._ - [Params Includes Submission Button Info](rails/params-includes-submission-button-info.md) - [Params Is A Hash With Indifferent Access](rails/params-is-a-hash-with-indifferent-access.md) - [Parse Query Params From A URL](rails/parse-query-params-from-a-url.md) +- [Parse Request Params In Rack::Attack Block](rails/parse-request-params-in-rack-attack-block.md) - [Perform SQL Explain With ActiveRecord](rails/perform-sql-explain-with-activerecord.md) - [Polymorphic Path Helpers](rails/polymorphic-path-helpers.md) - [Pretend Generations](rails/pretend-generations.md) diff --git a/rails/parse-request-params-in-rack-attack-block.md b/rails/parse-request-params-in-rack-attack-block.md new file mode 100644 index 0000000..40d9e57 --- /dev/null +++ b/rails/parse-request-params-in-rack-attack-block.md @@ -0,0 +1,39 @@ +# Parse Request Params In Rack::Attack Block + +The [`Rack::Attack` docs](https://github.com/rack/rack-attack) demonstrate a +way of throttling requests based on a value in the request params. In this +example, it is a Sign In endpoint and the `email` is the discriminating value. + +```ruby +Rack::Attack.throttle('limit logins per email', limit: 6, period: 60) do |req| + if req.path == '/login' && req.post? + # Normalize the email, using the same logic as your authentication process, to + # protect against rate limit bypasses. + req.params['email'].to_s.downcase.gsub(/\s+/, "") + end +end +``` + +Depending on the particulars of your middleware, it may be the case that +`req.params` is empty. That is because the request params need to be manually +parsed from the body of the request. + +An updated example that parses the params before accessing them could look like +this: + +```ruby +Rack::Attack.throttle('limit logins per email', limit: 6, period: 60) do |req| + if req.path == '/login' && req.post? + params = JSON.parse(req.body.string) + + # Normalize the email, using the same logic as your authentication process, to + # protect against rate limit bypasses. + params['email'].to_s.downcase.gsub(/\s+/, "") + end +end +``` + +You can pry into the block or add some logging to ensure that you are getting +at the POST params you are interested in. + +[source](https://github.com/rack/rack-attack/issues/189#issuecomment-744593703)