apiac_filter_throttler v1.0.0 APIacFilterThrottler View Source
An APIac.Filter
plug for API requests rate-limiting
This plug uses the Exhammer package as its backend. This library uses the token bucket algorithm, which means that this plug is mainly suitable for limiting abuses, not for accurate rate limiting. By default, a local ETS backend is launched on startup.
Plug options
key
: a(Plug.Conn.t -> String.t | {String.t, non_neg_integer(), non_neg_integer()})
function, taking in parameter the connection and returning either the key, or the tuple{key, scale, limit}
. No default value. Note that theAPIacFilterThrottler.Functions
provides with out-of-the-box functionsscale
: the time window of the token bucket algorithm, in milliseconds. No default value.limit
: the maximum limit of the token bucket algorithm, in attempt count. No default value.increment
: the increment of the token bucket algorithm (defaults to1
)backend
: Exhammer's backend, defaults tonil
exec_cond
: a(Plug.Conn.t() -> boolean())
function that determines whether this filter is to be executed or not. Defaults tofn _ -> true end
send_error_response
: function called when request is throttled. Defaults toElixir.APIacFilterThrottler.send_error_response/3
error_response_verbosity
: one of:debug
,:normal
or:minimal
. Defaults to:normal
Example
Allow 50 request / 10 seconds per subject and per client:
plug APIacFilterThrottler, key: &APIacFilterThrottler.Functions.throttle_by_subject_client/1,
scale: 10_000,
limit: 50
Allow 5000 requests / minute per client, only for machine-to-machine access:
plug APIacFilterThrottler, key: &APIacFilterThrottler.Functions.throttle_by_client/1,
exec_cond: &APIac.machine_to_machine?/1,
scale: 60_000,
limit: 5000
Security considerations
Consider the risk of collisions when constructing the key> For instance, a key function concatenating the ip address and a subject (username) would return the same key ("72.23.241.121edwards") for:
- a user "edwards" connecting from 72.23.241.121
- a user "1edwards" connecting from 72.23.241.12
The more control an attacker has on choosing the key parameters (e.g. the username), the easier to find a collision.
Finding a collision can result in a DOS for the legitimate requester.
Using a hash function such as :erlang.phash2/1
, MD5, etc. cam help mitigate the risk,
at the expense of performance. Also note that :erlang.phash2/1
is not a
collision-resistant hash function (as results are not uniformly distributed).
Link to this section Summary
Functions
Implementation of the APIac.Filter
behaviour.
Link to this section Functions
Implementation of the APIac.Filter
behaviour.
Verbosity
The following elements in the HTTP response are set depending on the value
of the :error_response_verbosity
option:
Error reponse verbosity | HTTP status | Headers | Body |
---|---|---|---|
:debug | Too many requests (429) | retry-after | APIac.Filter.Forbidden exception's message |
:normal | Too many requests (429) | retry-after | |
:minimal | Forbidden (403) |