Версия фреймворка: 8.x 5.4 4.2

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

Введение

Laravel включает простую в использовании абстракцию ограничения скорости, которая в сочетании с кешем вашего приложения обеспечивает простой способ ограничить любое действие в течение указанного периода времени.

Если вас интересует ограничение скорости входящих HTTP-запросов, обратитесь к документации посредника для ограничения частоты запросов.

Конфигурация кеша

Обычно ограничитель скорости использует кеш вашего приложения по умолчанию, как определено ключом default в файле конфигурации cache вашего приложения. Однако вы можете указать, какой драйвер кеша должен использовать ограничитель скорости, задав ключ limiter в файле конфигурации cache вашего приложения:

'default' => 'memcached',

'limiter' => 'redis',

Базовое использование

Фасад Illuminate\Support\Facades\RateLimiter может использоваться для взаимодействия с ограничителем скорости. Самый простой метод, предлагаемый ограничителем скорости - это метод attempt который ограничивает скорость данного обратного вызова на заданное количество секунд.

Метод attempt возвращает false если для обратного вызова не осталось доступных попыток; в противном случае метод attempt вернет результат обратного вызова или true. Первым аргументом, принимаемым методом attempt является «ключ» ограничителя скорости, который может быть любой строкой по вашему выбору, представляющей действие с ограничением скорости:

use Illuminate\Support\Facades\RateLimiter;

$executed = RateLimiter::attempt(
    'send-message:'.$user->id,
    $perMinute = 5,
    function() {
        // Send message...
    }
);

if (! $executed) {
  return 'Too many messages sent!';
}

Ручное увеличение числа попыток

Если вы хотите вручную взаимодействовать с ограничителем скорости, доступно множество других методов. Например, вы можете вызвать метод tooManyAttempts, чтобы определить, не превысил ли заданный ключ ограничителя скорости максимальное количество разрешенных попыток в минуту:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
    return 'Too many attempts!';
}

В качестве альтернативы вы можете использовать метод remaining для получения количества попыток, оставшихся для данного ключа. Если для данного ключа остались повторные попытки, вы можете вызвать метод hit, чтобы увеличить общее количество попыток:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
    RateLimiter::hit('send-message:'.$user->id);

    // Send message...
}

Определение доступности ограничителя скорости

Когда у ключа больше не осталось попыток, метод availableIn возвращает количество секунд, оставшихся до тех пор, пока не будут доступны новые попытки:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
    $seconds = RateLimiter::availableIn('send-message:'.$user->id);

    return 'You may try again in '.$seconds.' seconds.';
}

Очистка счетчика попыток

Вы можете сбросить количество попыток для данного ключа ограничителя скорости, используя метод clear. Например, вы можете сбросить количество попыток, когда данное сообщение прочитано получателем:

use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;

/**
 * Отметьте сообщение как прочитанное.
 *
 * @param  \App\Models\Message  $message
 * @return \App\Models\Message
 */
public function read(Message $message)
{
    $message->markAsRead();
    
    RateLimiter::clear('send-message:'.$message->user_id);
    
    return $message;
}