Site

Rate Limiter

O RateLimiter é um serviço nativo da MUCRM criado para proteger sua aplicação contra força bruta, spam, flood, tentativas repetidas de bots, abuso em formulários e ataques automatizados.

ℹ️Cache em Arquivos
Ele utiliza o sistema de cache em arquivos (FileCache), evitando sobrecarga no banco de dados durante ataques ou acessos massivos.

Importação e Instanciação

use MUCRM\engine\support\rate_limiter;

$rateLimiter = new rate_limiter();

Como Funciona

O fluxo padrão é:

  1. Verificar se excedeu limite
  2. Processar ação
  3. Se falhar, registrar tentativa
  4. Se sucesso, limpar histórico

Métodos Disponíveis

MétodoDescrição
tooManyAttempts($key, $max)Verifica se a chave ultrapassou o número máximo de tentativas
hit($key, $decaySeconds)Registra uma tentativa e aplica tempo de bloqueio em segundos
availableIn($key)Retorna em segundos quanto falta para liberar
clear($key)Limpa tentativas anteriores (use após sucesso)

tooManyAttempts()

if ($rateLimiter->tooManyAttempts($key, 5)) {
    // bloqueado
}

hit()

O segundo parâmetro é o tempo de bloqueio em segundos. Para passar minutos, multiplique: $minutes = 60 * 5;

$rateLimiter->hit($key, 120); // bloqueio por 120 segundos (2 min)

availableIn()

$seconds = $rateLimiter->availableIn($key);

clear()

$rateLimiter->clear($key);

Criando Chaves Inteligentes

Sempre use identificadores únicos:

Por IP

$key = 'login_attempts:' . $request->ip();

Por IP + Usuário (mais seguro)

$key = 'login_attempts:' .
       $request->ip() .
       $request->input('username');

Por Ação Específica

$key = 'comment_flood:' . $request->ip();

$key = 'register_attempts:' . $request->ip();

Exemplo Completo: Login

use MUCRM\engine\support\request;
use MUCRM\engine\support\rate_limiter;

public function login(request $request)
{
    $rateLimiter = new rate_limiter();

    $key = 'login_attempts:' .
           $request->ip() .
           $request->input("email");

    if ($rateLimiter->tooManyAttempts($key, 5)) {

        $seconds = $rateLimiter->availableIn($key);

        $tempoMsg = $seconds >= 60
            ? floor($seconds / 60) . " minutes"
            : $seconds . " seconds";

        return res()->error("Try again in {$tempoMsg}.")->back();
    }

    $credentials = $request->check([
        "email" => "required|email|min:4|max:10",
        "password" => "required|string|max:10",
        "password_confirmation" => "required|string|max:10|match:password",
    ], [
        "email.required" => "Informe seu email para acessar.",
        "password.required" => "A senha é obrigatória.",
    ]);

    $user = user::where("email", $credentials['email'])
        ->where("password", $credentials['password'])
        ->first();

    if (!$user) {

        $rateLimiter->hit($key, 120); // 120 segundos = 2 min

        return res()->error("Invalid username or password.")->back();
    }

    $rateLimiter->clear($key);

    Auth::login($user);

    return res()->success('Login ok!')->to('user.panel');
}

Exemplo: Protegendo Comentários

$key = 'comment_flood:' . $request->ip();

if ($rateLimiter->tooManyAttempts($key, 3)) {
    return res()->error('Please wait before commenting again.')->back();
}

$rateLimiter->hit($key, 60); // 60 segundos

Exemplo: Protegendo Cadastro

$key = 'register_attempts:' . $request->ip();

if ($rateLimiter->tooManyAttempts($key, 5)) {
    return res()->error('Too many attempts.')->back();
}

Boas Práticas

💡Recomendações
  • Use prefixos nas chaves.
  • Combine IP + usuário em login.
  • Limpe tentativas após sucesso.
  • Use limites baixos em áreas críticas.
  • Proteja login, cadastro, comentários e reset de senha.
  • Evite bloquear globalmente usuários inocentes.

Resumo Rápido

$rateLimiter = new RateLimiter();

$key = 'login:' . $request->ip();

$rateLimiter->tooManyAttempts($key, 5);

$rateLimiter->hit($key, 120); // 120 segundos

$rateLimiter->availableIn($key);

$rateLimiter->clear($key);