Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

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

Введение

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

{tip} Если вас интересует ограничение скорости входящих 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;
 
/**
* Mark the message as read.
*
* @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;
}