Обмеження частоти запитів

Для того, щоб уникнути зловживань, вам слід подумати про додавання обмеження частоти запитів до вашого API. Наприклад, ви можете обмежити використання вашого API до 100 запитів протягом 10 хвилин для кожного користувача. Якщо від користувача протягом цього періода часу надходить більша кількість запитів, буде повернута відповідь з кодом 429 ("занадто багато запитів").

Для того, щоб увімкнути обмеження частоти запитів, клас user identity повинен реалізовувати інтерфейс yii\filters\RateLimitInterface. Цей інтерфейс вимагає реалізації наступних трьох методів:

  • getRateLimit(): повертає максимальну кількість дозволених запитів та період часу, наприклад [100, 600], що означає не більше 100 викликів API прогятом 600 секунд.
  • loadAllowance(): повертає кількість дозволених запитів, що залишились, та мітку часу UNIX останньої перевірки обмеження.
  • saveAllowance(): зберігає кількість дозволених запитів та поточну мітку часу UNIX.

Ви можете використовувати два стовпці в таблиці user для зберігання кількості дозволених запитів та час останньої перевірки. У методах loadAllowance() та saveAllowance() можна реалізувати зчитування та зберігання значень цих стовбців відповідно до даних поточного аутентифікованого користувача. Для покращення швидкодії можна спробувати зберігати цю інформацію в кеш чи NoSQL-сховищі.

Реалізація у моделі User може виглядати наступним чином:

public function getRateLimit($request, $action)
{
    return [$this->rateLimit, 1]; // $rateLimit запитів на секунду
}

public function loadAllowance($request, $action)
{
    return [$this->allowance, $this->allowance_updated_at];
}

public function saveAllowance($request, $action, $allowance, $timestamp)
{
    $this->allowance = $allowance;
    $this->allowance_updated_at = $timestamp;
    $this->save();
}

Як тільки відповідний інтерфейс буде реалізований у класі identity, Yii почне автоматично перевіряти обмеження частоти запитів за допомогою фільтра дій yii\filters\RateLimiter для yii\rest\Controller. При перевищенні обмежень буде викинуто виключення yii\web\TooManyRequestsHttpException.

Ви можете налаштувати обмеження частоти викликів у ваших класах REST-контролерів наступним чином:

public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
    return $behaviors;
}

При увімкненому обмеженні частоти запитів кожна відповідь, за замовчуванням, повертається з наступними HTTP-заголовками, що містять таку інформацію про поточні обмеження:

  • X-Rate-Limit-Limit: максимальна кількість запитів, дозволена протягом періоду часу
  • X-Rate-Limit-Remaining: скільки залишилось дозволених запитів в поточний період часу
  • X-Rate-Limit-Reset: скільки часу у секундах потрібно почекати до отримання максимальної кількості дозволених запитів

Ви можете відключити ці заголовки, встановивши властивість yii\filters\RateLimiter::$enableRateLimitHeaders у false, як показано у прикладі вище.