Объяснение rate limiting в Laravel на реальных примерах

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

В Laravel встроена система ограничения частоты запросов (rate limiting), которая защищает приложение от перегрузки, спама и злоупотреблений. Эта статья объясняет, что такое rate limiting, почему это важно и как гибко применять его в ваших проектах.

Что такое rate limiting и зачем он нужен

Rate limiting - это механизм, который ограничивает, сколько раз можно выполнить определённое действие за фиксированный промежуток времени. Проще говоря, это ограничитель скорости для запросов к вашему приложению.

Это помогает:

  • Предотвратить перегрузку сервера при наплыве запросов.

  • Стабилизировать работу API и ускорить ответы.

  • Защитить от автоматизированных атак, ботов и грубой силы (brute-force).

  • Обеспечить справедливый доступ к ресурсам для всех пользователей.

  • Экономить ресурсы сервера и снизить расходы на инфраструктуру.

  • Защитить чувствительные маршруты (например, логин или регистрацию) от злоупотреблений.

Встроенный rate limiting в Laravel (рекомендуемый способ)

Laravel предлагает мощный и простой способ настройки ограничений через фасад RateLimiter::for(). Это позволяет определять именованные лимитеры, которые затем применяются через middleware.

Вот пример, который ограничивает отправку логинов с одного IP-адреса:

// Файл: App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;

public function boot(): void
{
    RateLimiter::for('login', function (Request $request) {
        return Limit::perMinute(5)
            ->by($request->ip())
            ->response(function () {
                return response()->json([
                    'message' => 'Слишком много попыток. Повторите позже.'
                ], 429);
            });
    });
}

Теперь вы можете применить этот лимитер к маршруту:

Route::middleware('throttle:login')->post('/login', [AuthController::class, 'login']);

В этом примере:

  • Пользователь может попытаться выполнить логин не более 5 раз в минуту.

  • Если лимит превышен, будет возвращён ответ с кодом 429 Too Many Requests и кастомным сообщением.

Стратегии применения rate limiting

Rate limiting можно адаптировать под разные сценарии. Ниже приведены четырёх примера паттернов, которые помогают защитить приложение в разных случаях.

1. Ограничение по роли пользователя

В SaaS-приложениях разные группы пользователей могут иметь разные уровни доступа. Например:

  • Администраторы - много запросов,

  • Платные пользователи - среднее количество,

  • Бесплатные пользователи - меньше запросов,

  • Гости - минимальное количество.

Пример middleware:

public function handle(Request $request, Closure $next){
    $role = $request->user()?->role ?? 'guest';
    $limits = ['admin' => 100, 'premium' => 200, 'free' => 60, 'guest' => 20];
    $maxAttempts = $limits[$role] ?? 20;
    $key = "rate:{$role}:" . ($request->user()?->id ?? $request->ip());

    if (RateLimiter::tooManyAttempts($key, $maxAttempts)) {
        return response()->json(['message' => 'Слишком много запросов.'], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Такой подход полезен, когда разные группы пользователей должны иметь разные лимиты.

2. Ограничение по IP

Иногда нужно ограничить поведение по IP-адресу. Например, если один и тот же адрес слишком часто вызывает API-эндпоинт.

Пример:

public function handle(Request $request, Closure $next)
{
    $ip = $request->ip();
    $key = 'rate_limit:ip:' . $ip;
    if (RateLimiter::tooManyAttempts($key, 60)) {
        return response()->json(['message' => 'Слишком много запросов с вашего IP.'], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Это удобно для анонимных маршрутов или API-вызовов без авторизации.

3. Мягкое ограничение всплесков трафика

Во время всплесков нагрузки (например, распродаж или акций) вы можете не запрещать запросы жёстко, а предоставить пользователям возможность "спокойно подождать" или получать упрощённые ответы.

Пример такого middleware:

public function handle(Request $request, Closure $next)
{
    $key = 'burst:' . $request->ip();
    if (RateLimiter::tooManyAttempts($key, 30)) {
        return response()->json(['message' => 'Слишком много запросов — попробуйте чуть позже'], 429);
    }

    RateLimiter::hit($key, 30);

    return $next($request);
}

Это даёт гибкий контроль над всплесками нагрузки.

4. Ограничение на основе API-токенов

Если ваше приложение предоставляет API с ключами доступа (API токенами), можно ограничивать запросы в зависимости от типа токена:

public function handle(Request $request, Closure $next)
{
    $token = $request->bearerToken();
    $key = 'rate_limit:token:' . ($token ?? $request->ip());
    if (RateLimiter::tooManyAttempts($key, 100)) {
        return response()->json(['message' => 'Превышен лимит запросов'], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Это особенно полезно, если у вас есть платные и бесплатные API-ключи с разными квотами.

Регистрация middleware

Когда вы создали свои rate limiting middleware, их нужно зарегистрировать в приложении:

// В Kernel.php
protected $routeMiddleware = [
    'role.throttle' => RateLimitByRole::class,
    'ip.throttle' => RateLimitByIP::class,
    'burst.throttle' => BurstLimit::class,
    'token.throttle' => RateLimitByToken::class,
];

После этого их можно применять к маршрутам, как обычные middleware.


Rate limiting - это не просто защита от злоумышленников. Это важная часть архитектуры высоконагруженного приложения, которая помогает:

  • Поддерживать скорость и стабильность API.

  • Снизить избыточную нагрузку на сервер.

  • Обеспечить справедливый доступ для всех пользователей.

  • Защитить чувствительные маршруты от атак типа brute-force и DDoS.

Laravel предоставляет мощные и гибкие инструменты для реализации rate limiting. Начните с простых настроек через RateLimiter::for() и постепенно адаптируйте стратегию под нужды вашего проекта.

Комментарии (0)

Войдите, чтобы оставить комментарий

Похожие статьи

PHP Generators

Статья рассказывает о PHP генераторах - что это, как они работают, зачем нужны и как использовать их в реальных проектах. Примеры включают чтение больших CSV и потоковую обработку данных.