Я использую Laravel для предоставления доступа к API для внутреннего мобильного приложения. Но служба находится за пределами нашей корпоративной сети, в то время как пользователи подключены к inte rnet через тот же маршрутизатор (который является корпоративной сетью).
Для предотвращения спама в таких маршрутах, как " Отправьте письмо еще раз", я создал свое промежуточное ПО, которое я могу применять только на желаемых маршрутах (регулирование).
Код выглядит следующим образом:
class ThrottleRoute
{
protected $limiter;
public function __construct(RateLimiter $limiter)
{
$this->limiter = $limiter;
}
public function handle($request, Closure $next, $max_attempts = 60, $decay_seconds = 60)
{
$key = $this->resolveRequestSignature($request);
$attempts = $this->limiter->hit($key, $decay_seconds);
if ($attempts > (int) $max_attempts) {
return abort(429);
}
return $next($request);
}
private function resolveRequestSignature($request)
{
$route = $request->route();
if (!$route) {
throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}
$route_part = $route->getDomain() . '|' . $route->uri;
$user_part = ($user = $request->user()) ? $user->getAuthIdentifier() : $request->ip();
return sha1("$route_part|$user_part");
}
}
Это хорошо работает, когда пользователи мобильных приложений проходят проверку подлинности (потому что в этом случае он будет использовать AuthIdentifier как часть уникального ключа).
Но когда люди не проходят проверку подлинности, у меня есть некоторые маршруты, которые я тоже хочу защитить, и в этом Я использую IP-адрес. Проблема в том, что многие из нас имеют один и тот же IP-адрес, и из-за этого очень быстро генерируется 429 ошибок, даже если пользователь еще не выполнил запрос (возможно, что-то вроде 100-500 пользователей, использующих приложение в одно и то же время на одном и том же сеть).
Я ищу решение для лучшей идентификации каждого пользователя, когда он не подключен и использует тот же внешний IP-адрес.