Обмеження частоти запитів

Вступ

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

Якщо вас цікавить обмеження частоти запитів вхідних HTTP-запитів, будь ласка, зверніться до документації middleware обмеження частоти запитів.

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

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

'default' => env('CACHE_STORE', 'database'),
 
'limiter' => 'redis',

Основне використання

The 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() {
// Відправити повідомлення...
}
);
 
if (! $executed) {
return 'Too many messages sent!';
}

Якщо необхідно, ви можете надати четвертий аргумент методу attempt, який є "швидкістю зменшення", або кількістю секунд до скидання доступних спроб. Наприклад, ми можемо змінити наведений вище приклад, щоб дозволити п'ять спроб кожні дві хвилини:

$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 'Too many attempts!';
}
 
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 'You may try again in '.$seconds.' 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;
}