Laravel - Ограничитель скорости не привязан к пользователю - PullRequest
0 голосов
/ 04 марта 2020

Я столкнулся с довольно странной проблемой, если я так говорю, пользователь API сообщает, что превышен лимит скорости API, при проверке этого кажется, что лимит скорости не привязан к конкретному c пользователь, а точнее для всех пользователей одновременно.

Поэтому, когда пользователь 1 делает запрос, ограничение скорости для других пользователей также будет снижено.

Я проверял это использование Почтальона при использовании двух отдельных токенов на предъявителя (сгенерированных для двух уникальных пользователей)

У кого-нибудь есть идея?

1 Ответ

0 голосов
/ 04 марта 2020

Встроенное промежуточное программное обеспечение Laravel ограничивает IP-адрес пользователя.

см. https://github.com/illuminate/routing/blob/master/Middleware/ThrottleRequests.php

protected function resolveRequestSignature($request)
    {
        if ($user = $request->user()) {
            return sha1($user->getAuthIdentifier());
        }

        if ($route = $request->route()) {
            return sha1($route->getDomain().'|'.$request->ip());
        }

        throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
    }

Это объясняет, почему вы видите ограничения, которые вы используете в своем локальном тесте. В зависимости от варианта использования вашего конечного пользователя, это, вероятно, объясняет и их проблемы. Испытывает ли это один или несколько человек с разными именами пользователей, но из одного и того же физического места?

Если вы думаете о том, каковы цели подобного газа, это имеет смысл. Случай использования дросселя, начинающегося заново, когда тот же самый конечный пользователь начинает использовать новое имя пользователя для попытки входа в систему, действительно имеет смысл только в сценарии тестирования и проблематичен c в производственных средах.

Если вы если вы хотите изменить это поведение, вы можете создать новое пользовательское промежуточное программное обеспечение в папке app/Http/Middleware, которое расширяет базу Illuminate\Routing\Middleware\ThrottleRequests.

В своем пользовательском промежуточном программном обеспечении вы можете затем переопределить метод resolveRequestSignature() и изменить это от ip к чему-то другому.

У вас нет аутентифицированного пользователя для работы, поэтому ваш выбор ограничен.

Если у вас есть пользователи, передающие заголовок ключа API, то есть разумный вариант. В зависимости от того, как вы это настроили, это будет выглядеть примерно так:

<?php

namespace App\Http\Middleware;

use Illuminate\Routing\Middleware\ThrottleRequests;

/**
 * Class ApiKeyBasedThrottleRequests  
 *  
 * 
 *
 * @package App\Http\Middleware
 */
class SessionBasedThrottleRequests extends ThrottleRequests
{
    /**
     * Override the default, which returns as signature
     * sha1($route->getDomain().'|'.$request->ip());
     *
     * Resolve request signature.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     *
     * @throws \RuntimeException
     */
    protected function resolveRequestSignature($request)
    {
        if ($user = $request->user()) {
            return sha1($user->getAuthIdentifier());
        }

        if ($route = $request->route()) {
            return sha1($route->getDomain().'|'. $request->header('api-key'));
        }

        throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
    }
}

Затем вам потребуется обновить ссылку на промежуточное ПО в файле app/Http/Kernel в массиве $routeMiddleware. Измените значение, назначенное клавише throttle, чтобы оно указывало на ваше новое пользовательское промежуточное ПО, вместо этого App\Http\Middleware;\ApiKeyBasedThrottleRequests::class, если \Illuminate\Routing\Middleware\ThrottleRequests::class

Если у вас нет ключа API для работы с вами, вы можете подумать и о сессии id, но если один пользователь пытается использовать разные имена пользователей в одном сеансе браузера, у вас все равно будет та же проблема. В этом случае вы можете посоветовать пользователю перезапустить браузер и повторить попытку. Тем не менее, это в основном создает обходной путь для цели газа.

Тщательно продумайте и осторожно подходите к этому. Несмотря на то, что имеет смысл сделать вещи гибкими, чтобы вы не блокировали пользователей, имейте в виду, что одна из целей дросселя - не дать потенциальным злоумышленникам атаковать грубой силой, чтобы обнаружить рабочие комбинации имени пользователя и пароля. Все, что вы здесь делаете, может дать им потенциальный обходной путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...