Фасад RateLimiter в Laravel 8

Фасад RateLimiter в Laravel 8

Потрясающий новый фасад 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.