rest-rate-limiting.md 2.48 KB
Newer Older
Qiang Xue committed
1
Rate Limiting
Qiang Xue committed
2
=============
Qiang Xue committed
3

Larry Ullman committed
4
To prevent abuse, you should consider adding *rate limiting* to your APIs. For example, you may want to limit the API usage
Qiang Xue committed
5
of each user to be at most 100 API calls within a period of 10 minutes. If too many requests are received from a user
Larry Ullman committed
6
within the stated period of the time, a response with status code 429 (meaning "Too Many Requests") should be returned.
Qiang Xue committed
7 8

To enable rate limiting, the [[yii\web\User::identityClass|user identity class]] should implement [[yii\filters\RateLimitInterface]].
Larry Ullman committed
9
This interface requires implementation of three methods:
Qiang Xue committed
10

Larry Ullman committed
11
* `getRateLimit()`: returns the maximum number of allowed requests and the time period (e.g., `[100, 600]` means there can be at most 100 API calls within 600 seconds).
Qiang Xue committed
12
* `loadAllowance()`: returns the number of remaining requests allowed and the corresponding UNIX timestamp
Larry Ullman committed
13 14
  when the rate limit was last checked.
* `saveAllowance()`: saves both the number of remaining requests allowed and the current UNIX timestamp.
Qiang Xue committed
15

Larry Ullman committed
16
You may want to use two columns in the user table to record the allowance and timestamp information. With those defined, then `loadAllowance()` and `saveAllowance()` can be implemented to read and save the values
Qiang Xue committed
17
of the two columns corresponding to the current authenticated user. To improve performance, you may also
Larry Ullman committed
18
consider storing these pieces of information in a cache or NoSQL storage.
Qiang Xue committed
19 20 21

Once the identity class implements the required interface, Yii will automatically use [[yii\filters\RateLimiter]]
configured as an action filter for [[yii\rest\Controller]] to perform rate limiting check. The rate limiter
Larry Ullman committed
22 23 24 25
will throw a [[yii\web\TooManyRequestsHttpException]] when the rate limit is exceeded. 

You may configure the rate limiter
as follows in your REST controller classes:
Qiang Xue committed
26 27 28 29

```php
public function behaviors()
{
Qiang Xue committed
30 31 32
    $behaviors = parent::behaviors();
    $behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
    return $behaviors;
Qiang Xue committed
33 34 35 36 37 38
}
```

When rate limiting is enabled, by default every response will be sent with the following HTTP headers containing
the current rate limiting information:

Larry Ullman committed
39 40 41
* `X-Rate-Limit-Limit`, the maximum number of requests allowed with a time period
* `X-Rate-Limit-Remaining`, the number of remaining requests in the current time period
* `X-Rate-Limit-Reset`, the number of seconds to wait in order to get the maximum number of allowed requests
Qiang Xue committed
42 43

You may disable these headers by configuring [[yii\filters\RateLimiter::enableRateLimitHeaders]] to be false,
Larry Ullman committed
44
as shown in the above code example.