Skip to content

Commit 3270682

Browse files
committed
Add Parse Request Params In Rack::Attack Block as a Rails TIL
1 parent 5445916 commit 3270682

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
1010

1111
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
1212

13-
_1321 TILs and counting..._
13+
_1322 TILs and counting..._
1414

1515
---
1616

@@ -845,6 +845,7 @@ _1321 TILs and counting..._
845845
- [Params Includes Submission Button Info](rails/params-includes-submission-button-info.md)
846846
- [Params Is A Hash With Indifferent Access](rails/params-is-a-hash-with-indifferent-access.md)
847847
- [Parse Query Params From A URL](rails/parse-query-params-from-a-url.md)
848+
- [Parse Request Params In Rack::Attack Block](rails/parse-request-params-in-rack-attack-block.md)
848849
- [Perform SQL Explain With ActiveRecord](rails/perform-sql-explain-with-activerecord.md)
849850
- [Polymorphic Path Helpers](rails/polymorphic-path-helpers.md)
850851
- [Pretend Generations](rails/pretend-generations.md)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Parse Request Params In Rack::Attack Block
2+
3+
The [`Rack::Attack` docs](https://github.com/rack/rack-attack) demonstrate a
4+
way of throttling requests based on a value in the request params. In this
5+
example, it is a Sign In endpoint and the `email` is the discriminating value.
6+
7+
```ruby
8+
Rack::Attack.throttle('limit logins per email', limit: 6, period: 60) do |req|
9+
if req.path == '/login' && req.post?
10+
# Normalize the email, using the same logic as your authentication process, to
11+
# protect against rate limit bypasses.
12+
req.params['email'].to_s.downcase.gsub(/\s+/, "")
13+
end
14+
end
15+
```
16+
17+
Depending on the particulars of your middleware, it may be the case that
18+
`req.params` is empty. That is because the request params need to be manually
19+
parsed from the body of the request.
20+
21+
An updated example that parses the params before accessing them could look like
22+
this:
23+
24+
```ruby
25+
Rack::Attack.throttle('limit logins per email', limit: 6, period: 60) do |req|
26+
if req.path == '/login' && req.post?
27+
params = JSON.parse(req.body.string)
28+
29+
# Normalize the email, using the same logic as your authentication process, to
30+
# protect against rate limit bypasses.
31+
params['email'].to_s.downcase.gsub(/\s+/, "")
32+
end
33+
end
34+
```
35+
36+
You can pry into the block or add some logging to ensure that you are getting
37+
at the POST params you are interested in.
38+
39+
[source](https://github.com/rack/rack-attack/issues/189#issuecomment-744593703)

0 commit comments

Comments
 (0)