Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x Ограничение частоты запросов

Ограничение частоты запросов

10.x 7 мар 2026 г.

#Введение

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

Примечание

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

#Настройка кэша

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

'default' => 'memcached',

'limiter' => 'redis',

#Основное использование

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

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

use Illuminate\Support\Facades\RateLimiter;

$executed = RateLimiter::attempt(
    'send-message:'.$user->id,
    $perMinute = 5,
    function() {
        // Отправить сообщение...
    }
);

if (! $executed) {
  return 'Слишком много отправленных сообщений!';
}

При необходимости вы можете передать четвёртый аргумент в метод attempt — "время сброса" (decay rate), то есть количество секунд до сброса доступных попыток. Например, изменим пример выше, чтобы разрешить пять попыток каждые две минуты:

$executed = RateLimiter::attempt(
    'send-message:'.$user->id,
    $perTwoMinutes = 5,
    function() {
        // Отправить сообщение...
    },
    $decayRate = 120,
);

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

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

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
    return 'Слишком много попыток!';
}

RateLimiter::increment('send-message:'.$user->id);

// Отправить сообщение...

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

use Illuminate\Support\Facades\RateLimiter;

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

    // Отправить сообщение...
}

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

RateLimiter::increment('send-message:'.$user->id, amount: 5);

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

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

use Illuminate\Support\Facades\RateLimiter;

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

    return 'Вы сможете попробовать снова через '.$seconds.' секунд.';
}

RateLimiter::increment('send-message:'.$user->id);

// Отправить сообщение...

#Сброс попыток

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

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

/**
 * Отметить сообщение как прочитанное.
 */
public function read(Message $message): Message
{
    $message->markAsRead();

    RateLimiter::clear('send-message:'.$message->user_id);

    return $message;
}