Ограничение скорости
Введение
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;}