marcelocardozo/antibot-laravel
最新稳定版本:v1.0.7
Composer 安装命令:
composer require marcelocardozo/antibot-laravel
包简介
Sistema de detecção e bloqueio de bots, proxies e VPNs para Laravel
README 文档
README
Sistema de detecção e bloqueio de bots, proxies e VPNs para Laravel.
Detecta automaticamente ferramentas de automação (Selenium, Puppeteer, Playwright, Cypress, PhantomJS, etc.), analisa fingerprints do navegador, verifica proxies/VPNs via ProxyCheck.io e bloqueia visitantes suspeitos com base em um sistema de pontuação configurável.
Requisitos
- PHP 8.2+
- Laravel 11, 12 ou 13
- Chave de API do ProxyCheck.io (gratuito)
Instalação
composer require marcelocardozo/antibot-laravel
Publicar configuração, migrations e assets:
php artisan vendor:publish --provider="MarceloCardozo\Antibot\AntibotServiceProvider"
Ou publicar separadamente:
# Apenas configuração php artisan vendor:publish --tag=antibot-config # Apenas migrations php artisan vendor:publish --tag=antibot-migrations # Apenas assets (JS) php artisan vendor:publish --tag=antibot-assets # Apenas views (templates) php artisan vendor:publish --tag=antibot-views
Executar as migrations:
php artisan migrate
Configuração
Adicione ao .env:
ANTIBOT_PROXYCHECK_API_KEY=sua-chave-aqui ANTIBOT_TEST_IP=192.145.220.95
| Variável | Descrição |
|---|---|
ANTIBOT_PROXYCHECK_API_KEY |
Chave de API do ProxyCheck.io |
ANTIBOT_TEST_IP |
IP usado em localhost para testes (substitui 127.0.0.1) |
O arquivo config/antibot.php contém todas as opções:
return [ 'route_prefix' => 'antibot', // Prefixo das rotas 'route_middleware' => ['web'], // Middleware das rotas 'pagina_inicial' => '/', // Página com detecção completa 'redirect_url' => '', // Redirecionar após aprovação (vazio = não redireciona) 'block_redirect_url' => '/', // Não verificados → página de verificação 'bloqueado_url' => '', // Bloqueados → 404 (vazio) ou URL customizada 'tempo_minimo' => 5000, // Tempo mínimo de verificação (ms) 'tela_carregamento' => 'spinner', // Template: 'spinner' ou 'cloudflare' 'score_minimo' => 50, // Score mínimo para bloquear 'bloquear_bot' => true, // Bloquear bots detectados 'bloquear_proxy' => true, // Bloquear proxies 'bloquear_vpn' => true, // Bloquear VPNs 'paises_permitidos' => ['BR'], // Países permitidos (vazio = todos) 'regras' => [ ... ], // 40+ regras de detecção com pontuação ];
Uso
1. Página inicial (detecção completa)
Na Blade da página onde o visitante entra no site, adicione a diretiva @antibot:
<!DOCTYPE html> <html> <head></head> <body> @antibot <h1>Meu site</h1> </body> </html>
Quando o visitante acessa a página:
- A página é ocultada e um loading é exibido
- 40+ verificações client-side são executadas
- APIs server-side analisam IP, proxy, VPN e User-Agent
- O resultado é salvo no banco de dados
- Se aprovado: a página é liberada
- Se bloqueado: redireciona para
block_redirect_urlou exibe 404
2. Páginas secundárias (verificação rápida)
Para páginas internas que só precisam verificar se o visitante já foi aprovado:
<body> @antibotVerify <h1>Página interna</h1> </body>
3. Middleware (proteção server-side)
Para proteger rotas no server-side (bloqueia bots que pulam o JavaScript):
// routes/web.php Route::middleware('antibot.verify')->group(function () { Route::get('/area-protegida', [MeuController::class, 'index']); Route::get('/checkout', [CheckoutController::class, 'index']); });
O middleware verifica no banco se o IP do visitante já foi aprovado. Se não existir registro ou se estiver bloqueado, redireciona para block_redirect_url ou retorna 404.
4. Combinando proteções
Para proteção máxima, combine middleware + diretiva Blade:
// routes/web.php Route::middleware('antibot.verify')->group(function () { Route::get('/oferta', [OfertaController::class, 'index']); });
{{-- resources/views/oferta/index.blade.php --}} <body> @antibot <h1>Oferta exclusiva</h1> </body>
Redirecionamento
O pacote usa duas configs separadas para redirecionamento:
block_redirect_url — Visitantes não verificados
Usado pelo middleware (antibot.verify) e pela diretiva @antibotVerify. Redireciona visitantes que ainda não passaram pela verificação. Normalmente aponta para a página que contém @antibot.
// config/antibot.php // Padrão: redireciona para a página inicial (onde @antibot faz a verificação) 'block_redirect_url' => '/', // Path relativo 'block_redirect_url' => '/verificacao', // Vazio = exibe o template 404 do pacote 'block_redirect_url' => '',
bloqueado_url — Visitantes bloqueados
Usado pela diretiva @antibot quando a detecção identifica um bot, proxy, VPN ou score alto. Define para onde o visitante bloqueado é enviado.
// config/antibot.php // Padrão: exibe o template 404 do pacote 'bloqueado_url' => '', // Path relativo 'bloqueado_url' => '/acesso-negado', // URL externa 'bloqueado_url' => 'https://google.com',
Facade
O pacote disponibiliza uma Facade para uso programático:
use MarceloCardozo\Antibot\Facades\Antibot; // Resolver IP real do visitante $ip = Antibot::resolveIp($request); // Verificar proxy/VPN $data = Antibot::check($ip); // Retorna: ['ip', 'asn', 'provider', 'isocode', 'city', 'proxy', 'vpn', ...] // Detectar dispositivo $device = Antibot::detect($request->userAgent()); // Retorna: ['bot', 'client_name', 'device_type', 'os_name', ...] // Flags de servidor suspeitas $flags = Antibot::getServerFlags($request); // Retorna: ['tool_ua', 'short_ua', 'no_accept_language', ...]
Models
O pacote registra dois models Eloquent que permitem consultar os dados de detecção no seu código:
MarceloCardozo\Antibot\Models\Acesso— Registro de cada visitante analisadoMarceloCardozo\Antibot\Models\Navegacao— Páginas visitadas por cada acesso
Campos disponíveis
Acesso:
| Campo | Tipo | Descrição |
|---|---|---|
id |
bigint | ID auto-incremento |
data_hora |
timestamp | Data/hora do acesso |
ip |
string | IP do visitante |
url |
text | URL acessada |
asn |
string | ASN do provedor |
hostname |
string | Hostname do IP |
provider |
string | Provedor de internet |
organisation |
string | Organização |
isocode |
string | Código do país (BR, US, etc.) |
regioncode |
string | Código da região |
city |
string | Cidade |
proxy |
string | "yes" ou "no" |
vpn |
string | "yes" ou "no" |
bot |
string | "yes" ou "no" |
client_name |
string | Navegador (Chrome, Firefox, etc.) |
client_type |
string | Tipo do client (browser, app, etc.) |
client_version |
string | Versão do navegador |
device_brand |
string | Marca do dispositivo |
device_model |
string | Modelo do dispositivo |
device_type |
string | Tipo (desktop, smartphone, tablet) |
os_name |
string | Sistema operacional |
os_platform |
string | Plataforma |
os_version |
string | Versão do SO |
os_family |
string | Família do SO |
bloqueado |
string | "true" ou "false" |
motivo_bloqueio |
text | Motivo(s) do bloqueio |
created_at |
timestamp | Criado em |
updated_at |
timestamp | Atualizado em |
Navegacao:
| Campo | Tipo | Descrição |
|---|---|---|
id |
bigint | ID auto-incremento |
data_hora |
timestamp | Data/hora da navegação |
ip |
string | IP do visitante |
url |
text | URL visitada |
referrer |
text | Página de origem |
acesso_id |
bigint | FK para antibot_acessos |
created_at |
timestamp | Criado em |
updated_at |
timestamp | Atualizado em |
Exemplo em Controller
<?php namespace App\Http\Controllers; use MarceloCardozo\Antibot\Models\Acesso; use MarceloCardozo\Antibot\Models\Navegacao; class AntibotController extends Controller { // Listar todos os acessos com paginação public function index() { $acessos = Acesso::latest()->paginate(20); return view('antibot.index', compact('acessos')); } // Detalhes de um acesso específico + suas navegações public function show(Acesso $acesso) { $acesso->load('navegacoes'); return view('antibot.show', compact('acesso')); } // Listar apenas bloqueados public function bloqueados() { $bloqueados = Acesso::where('bloqueado', 'true') ->latest() ->paginate(20); return view('antibot.bloqueados', compact('bloqueados')); } // Estatísticas public function stats() { $total = Acesso::count(); $bloqueados = Acesso::where('bloqueado', 'true')->count(); $aprovados = Acesso::where('bloqueado', 'false')->count(); $proxies = Acesso::where('proxy', 'yes')->count(); $vpns = Acesso::where('vpn', 'yes')->count(); $bots = Acesso::where('bot', 'yes')->count(); $hoje = Acesso::whereDate('created_at', today())->count(); $bloqueadosHoje = Acesso::where('bloqueado', 'true') ->whereDate('created_at', today()) ->count(); return view('antibot.stats', compact( 'total', 'bloqueados', 'aprovados', 'proxies', 'vpns', 'bots', 'hoje', 'bloqueadosHoje' )); } }
Consultas úteis
use MarceloCardozo\Antibot\Models\Acesso; use MarceloCardozo\Antibot\Models\Navegacao; // Últimos 10 acessos bloqueados $bloqueados = Acesso::where('bloqueado', 'true') ->latest() ->take(10) ->get(); // Acessos de um IP específico $acessos = Acesso::where('ip', '177.0.0.1')->get(); // Verificar se um IP está bloqueado $estaBloqueado = Acesso::where('ip', '177.0.0.1') ->latest() ->first() ?->isBloqueado(); // true ou false // Navegação de um acesso (páginas visitadas) $acesso = Acesso::find(1); $paginas = $acesso->navegacoes; // Acessos por país $porPais = Acesso::select('isocode') ->selectRaw('count(*) as total') ->groupBy('isocode') ->orderByDesc('total') ->get(); // Acessos com proxy ou VPN $suspeitos = Acesso::where('proxy', 'yes') ->orWhere('vpn', 'yes') ->latest() ->get(); // Total de bloqueados hoje $total = Acesso::where('bloqueado', 'true') ->whereDate('created_at', today()) ->count(); // Acessos de um navegador específico $chrome = Acesso::where('client_name', 'Chrome')->get(); // Acessos mobile bloqueados $mobileBloqueados = Acesso::where('device_type', 'smartphone') ->where('bloqueado', 'true') ->get();
Relacionamentos
// Acesso -> Navegacoes (HasMany) $acesso = Acesso::find(1); $navegacoes = $acesso->navegacoes; // Collection de Navegacao // Navegacao -> Acesso (BelongsTo) $navegacao = Navegacao::find(1); $acesso = $navegacao->acesso; // Model Acesso // Eager loading $acessos = Acesso::with('navegacoes')->latest()->get();
Regras de detecção
O sistema usa 40+ regras com pontuação individual. Quando a soma dos pontos atinge o score_minimo (padrão: 50), o visitante é bloqueado.
Automação direta (80 pts cada)
| Regra | Detecta |
|---|---|
webdriver |
navigator.webdriver === true |
chromedriver |
Variáveis $cdc_ injetadas pelo ChromeDriver |
selenium |
Propriedades globais do Selenium |
puppeteer |
__puppeteer_evaluation_script__ |
playwright |
__playwright, __pw_manual |
cypress |
window.Cypress, window.cy |
phantomjs |
callPhantom, _phantom |
nightmare |
__nightmare |
webdriverio |
wdio, __wdio |
testcafe |
%testCafeDriverInstance% |
browserless |
__browserless, __chrome_aws_lambda |
stack_automacao |
Stack trace com nomes de ferramentas |
Fingerprint e ambiente
| Regra | Pts | Detecta |
|---|---|---|
ua_suspeito |
60 | Keywords de bot no User-Agent |
webdriver_patched |
60 | Undetected-chromedriver (getter customizado) |
chrome_falso |
30 | UA diz Chrome mas window.chrome ausente |
webgl_software |
30 | Renderer software (SwiftShader, Mesa) |
tela_zero |
30 | Dimensões da tela = 0 |
canvas_vazio |
25 | Canvas renderiza imagem vazia |
mobile_sem_touch |
25 | UA mobile sem suporte touch |
sem_color_depth |
20 | Color depth inválido |
platform_mismatch |
20 | UA e navigator.platform divergem |
perm_inconsistente |
20 | Permissões inconsistentes |
audio_vazio |
20 | Audio fingerprint vazio |
Para a lista completa, consulte config/antibot.php.
Desativar uma regra
// config/antibot.php 'regras' => [ 'historico_curto' => ['ativo' => false, 'pts' => 5], // desativada 'webdriver' => ['ativo' => true, 'pts' => 80], // ativa ],
Templates de loading
Dois templates disponíveis, configuráveis em config/antibot.php:
spinner— Spinner minimalista (padrão)cloudflare— Visual estilo Cloudflare security check
'tela_carregamento' => 'cloudflare',
Para personalizar, publique as views e edite em resources/views/vendor/antibot/templates/.
Rotas registradas
| Método | URI | Descrição |
|---|---|---|
| GET | /antibot/config |
Configuração pública (JSON) |
| GET | /antibot/api/proxycheck |
Detecção de proxy/VPN |
| GET | /antibot/api/device-detector |
Detecção de dispositivo |
| POST | /antibot/api/salvar |
Salvar registro de acesso |
| GET | /antibot/api/sessao |
Verificar status do visitante |
| POST | /antibot/api/navegacao |
Registrar navegação |
| GET | /antibot/templates/{template} |
Templates (404, spinner, cloudflare) |
O prefixo /antibot é configurável via config('antibot.route_prefix').
Licença
MIT
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-12