A configurable Rails engine that provides a common way of reducing API abuse, throttling consumers' requests and blocking undesired pentesters and robots.
Add this line to your application's Gemfile:
gem 'nexaas-throttle'
And then execute:
$ bundle
Or install it yourself as:
$ gem install nexaas-throttle
In a Rails initializer file such as config/initializers/nexaas_throttle.rb
, put something like this:
require "nexaas/throttle"
Nexaas::Throttle.configure do |config|
config.throttle = true
config.track = true
config.period = 1.minute
config.limit = 2
config.request_identifier = MyRequestIdentifier
config.redis_options = {
host: "localhost",
port: 6379,
db: 0,
namespace: "nexaas:throttle"
}
config.ignored_user_agents = [/[Gg]oogle/, /Amazon/]
config.assets_extensions = %w[bmp tiff css js jpg jpeg png gif woff ttf svg]
end
Option | Description | Default |
---|---|---|
throttle |
Whether or not requests are throttled. | true |
track |
Whether or not requests are tracked. | true |
period |
The size of the throttle window. | 1 minute |
limit |
How many requests a consumer can do during a window until he starts being throttled. | 60 requests |
request_identifier |
The class that will handle request identification. See Request Identification for more details. | nil |
redis_options |
Redis hash configuration where requests counters are persisted. |
{ host: "localhost", port: 6379, db: 0, namespace: "nexaas:throttle" } |
ignored_user_agents |
An array of User Agents that should be ignored by the throttler. Values are regexes that will be matched against the request User-Agent | nil |
assets_extensions |
An array of file extensions considered to be asset-related. Values are strings that will be matched against the request path. Paths that match will be not be throttled | %w[css js jpg jpeg png gif woff ttf svg] |
Nexaas::Throttle
doesn't know how to identify a consumer. Some applications might rely on request IP, others on an API TOKEN. You must provide a way of getting an unique token
that identify a request consumer.
If there is no token, the request will go through and won't be accounted for.
Nexaas::Throttle
do this by providing a configuration request_identifier
, a class where your application would keep the logic that identifies a consumer. This class must have the following
interface:
class MyRequestIdentifier
def initialize(request)
@request = request
end
def token
@request.ip
# or @request.env["HTTP_AUTHORIZATION"]
# or User.find_by(token: @request.params[:token])
# or Cache.read(@request.params[:token])
end
end
In order to track your requests, you must subscribe to a event triggered by Rack::Attack
gem as below:
ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, request|
if request.env["rack.attack.matched"] == "nexaas/track" && request.env["rack.attack.match_type"] == :track
# Put your tracking logic here
# You can use request.env["nexaas.token"] to obtain the token provided by your request_identifier
end
end
If you want, you can access the request token by inspecting request.env["nexaas.token"]
. This is the token your request_identifier
provided after evaluating the request.
Rate limit headers are available for all request responses and provide information for API users. They are the following:
"X-RateLimit-Limit" # Total of requests allowed until next reset.
"X-RateLimit-Remaining" # Amount of requests the user can still send before being throttled.
"X-RateLimit-Reset" # Epoch time for the reset of the request count.
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/myfreecomm/nexaas-throttle.
The gem is available as open source under the terms of the MIT License.