API RESTful - Ограничение скорости

Чтобы предотвратить злоупотребления, вам следует рассмотреть возможность добавления ограничения скорости для ваших API. Например, вы можете ограничить использование API для каждого пользователя не более чем 100 вызовами API в течение 10 минут. Если слишком много запросов получено от пользователя в течение указанного периода времени, ответ с кодом состояния 429 (что означает «Слишком много запросов») должен быть возвращен.

Чтобы включить ограничение скорости, класс идентификации пользователя должен реализовывать yii\filters\RateLimitInterface. Этот интерфейс требует реализации трех методов:

  • GetRateLimit(): возвращает максимальное количество разрешенных запросов и период времени (например, [100, 600] означает, что в течение 600 секунд может быть не более 100 вызовов API).
  • LoadAllowance(): возвращает число оставшихся разрешенных запросов и соответствующую временную метку UNIX, когда последний предел скорости был установлен.
  • SaveAllowance(): сохраняет как количество оставшихся разрешенных запросов, так и текущую временную метку UNIX.

Вы можете использовать два столбца в пользовательской таблице для записи информации о припуске и отметке времени. С определенными, то 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();
}

Когда класс идентификации реализует требуемый интерфейс, 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, как показано в приведенном выше примере кода.