1
0
mirror of https://github.com/jbranchaud/til synced 2026-01-02 22:58:01 +00:00

Add Parse Request Params In Rack::Attack Block as a Rails TIL

This commit is contained in:
jbranchaud
2023-07-06 13:41:14 -05:00
parent 5445916004
commit 32706827e9
2 changed files with 41 additions and 1 deletions

View File

@@ -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)

View File

@@ -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)