Потрясающий новый фасад RateLimiter
делает управление скоростью обработки запросов простым, масштабируемым и приятным в использовании. Подумайте о рефакторинге ваших ограничителей, если переходите на Laravel 8.
В предыдущих версиях Laravel, вплоть до 7-ой, когда нужно было ограничить скорость обработки запросов на определенных маршрутов, то это можно было сделать применив мидлвар throttle
:
Route::get('admin/profile', function () { // })->middleware('auth', 'throttle:30,1');
Параметр 30,1
в этой конфигурации означает, что аутентифицированный пользователь может получить доступ к маршруту 30 раз в минуту. Если пользователь превысит этот лимит в течение указанного периода, то Laravel вернет ошибку 429 Too Many Requests
.
Числа захардкожены и невозможно настроить их динамическое изменение или повторное использование этой настроенной конфигурации для других маршрутов.
Laravel 8 решает эти проблемы вводя фасад RateLimiter
. Давайте рассмотрим его более подробно.
Фасад RateLimiter
С помощью фасада Illuminate\Support\Facades\RateLimiter
вы можете задавать «именованные» ограничители скорости различных конфигураций. Поскольку у них теперь есть имена, то вы можете использовать их для разных маршрутов и их групп.
Кроме того, вы можете создать несколько ограничителей скорости для разных вариантов использования.
Ограничители прописываются в методе boot
в AppServiceProvider
. Например, если вам нужен ограничитель limitadmin
, то вы можете сделать это так:
namespace App\Providers; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Http\Request; use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot() { RateLimiter::for('limitadmin', function (Request $request) { return Limit::perMinute(3); }); } }
Метод for
в RateLimiter
принимает два параметра:
- Название ограничителя скорости
- Замыкание, которое возвращает конфигурацию ограничения для маршрутов
В Замыкании вы можете вернуть фактическое ограничение скорости запросов, используя метод perMinute
из Illuminate\Cache\RateLimiting\Limit
, в котором вы указывается, сколько раз в минуту пользователю разрешен доступ к маршруту.
Использование именованного ограничителя скорости
После того, как вы создадите ограничитель скорости — его можно назначить маршруту:
Route::get('profile', function () { // })->middleware(['throttle:limitadmin']);
Как видите, вместо закардкоженной конфигурации, вы просто используете имя ограничителя. Это читабельно и доступно для многоразового использования.
Динамические ограничители
Можно создавать ограничители скорости запросов, основанные на определенных условиях.
Замыкание метода for
получает объект Illuminate\Http\Request
и мы можем его использовать. Например, если нужно ограничивать только обычных пользователей и не применяться к администраторам, то мы можем сделать это так:
RateLimiter::for('limitadmin', function (Request $request) { return $request->user()->type == 'admin' ? Limit::none() : Limit::perMinute(3); });
Как видите, с помощью метода none()
можно задать неограниченную скорость обработки запросов.
Кастомный ответ
Также, вместо стандартного 429 Too Many Requests
, можно вернуть свой собственный ответ используя метод response
:
RateLimiter::for('book', function (Request $request) { return Limit::perMinute(3)->response(function() { return new Response('Beep! Beep! Too many attempts'); }); });
Автор: Amit Merchant
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.