Laravel Middleware em profundidade: Autenticação, Rate Limiting e Middleware personalizado
Guia completo sobre middleware no Laravel com exemplos práticos: guards de autenticação, limitação de taxa com throttle, criação de middleware personalizado e padrões avançados para aplicações em produção.

O middleware do Laravel funciona como uma camada de filtragem entre as requisições HTTP recebidas e a lógica da aplicação. Cada requisição percorre um pipeline de classes middleware antes de chegar a um controller, e cada resposta viaja de volta pelo mesmo pipeline. Compreender esse mecanismo é fundamental para construir aplicações Laravel seguras e de alto desempenho em 2026.
O middleware intercepta requisições HTTP antes que elas alcancem as rotas. O Laravel 12 registra todos os middleware em bootstrap/app.php usando uma API fluente. Os middleware integrados gerenciam autenticação, proteção CSRF, gerenciamento de sessões e limitação de taxa nativamente.
Como funciona o pipeline de middleware no Laravel
O kernel HTTP do Laravel processa cada requisição através de uma pilha de middleware. Cada middleware recebe a requisição, executa sua lógica e então passa a requisição para a próxima camada via $next($request) ou interrompe o pipeline retornando uma resposta diretamente.
Essa arquitetura segue o padrão de projeto Chain of Responsibility. Um middleware pode atuar antes de a requisição alcançar o controller (por exemplo, verificações de autenticação), depois que a resposta é gerada (por exemplo, adicionando cabeçalhos), ou em ambos os momentos.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class LogRequestTime
{
public function handle(Request $request, Closure $next): Response
{
$start = microtime(true); // Capture start time
$response = $next($request); // Pass to next middleware
$duration = microtime(true) - $start;
Log::info('Request completed', [
'url' => $request->url(),
'method' => $request->method(),
'duration' => round($duration * 1000, 2) . 'ms',
]);
return $response; // Return response up the stack
}
}Esse middleware envolve a requisição: ele registra o tempo de início antes do processamento e registra a duração depois que a resposta retorna. Esse padrão antes/depois é central no funcionamento dos middleware.
Middleware de autenticação: protegendo rotas
O Laravel inclui o alias de middleware auth, mapeado para Illuminate\Auth\Middleware\Authenticate. Ao aplicá-lo a uma rota, apenas usuários autenticados conseguem acessá-la. Usuários não autenticados recebem uma resposta 401 (API) ou são redirecionados para a página de login (web).
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ProfileController;
// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// Group protection for multiple routes
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
Route::put('/profile', [ProfileController::class, 'update']);
Route::delete('/profile', [ProfileController::class, 'destroy']);
});Autenticação com múltiplos guards
Aplicações com vários tipos de usuários (painel administrativo, área do cliente, API) se beneficiam da autenticação baseada em guards. O middleware auth aceita um parâmetro de guard para especificar qual driver de autenticação deve ser utilizado.
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::apiResource('/orders', OrderController::class);
});
// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'users']);
});O parâmetro de guard após os dois pontos indica ao Laravel qual configuração de autenticação verificar. Essa abordagem mantém a lógica de autenticação organizada e separada entre as diferentes partes da aplicação.
O middleware guest é o inverso do auth — permite a passagem apenas de usuários não autenticados. Ao aplicá-lo às rotas de login e cadastro, impede-se que usuários já autenticados acessem essas páginas.
Limitação de taxa com o middleware Throttle
A limitação de taxa via middleware no Laravel protege as rotas contra abusos usando o middleware integrado throttle. Sua forma mais simples aceita dois parâmetros: o número máximo de requisições e a janela de tempo em minutos.
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
});
// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
});Rate limiters nomeados para controle avançado
Definir rate limiters nomeados no AppServiceProvider oferece controle granular sobre os limites com base no contexto do usuário. Essa abordagem é mais flexível do que os parâmetros throttle inline.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;
public function boot(): void
{
// API rate limiter with tiered access
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if ($user?->hasSubscription('enterprise')) {
return Limit::perMinute(500)->by($user->id); // Enterprise: 500/min
}
if ($user) {
return Limit::perMinute(100)->by($user->id); // Authenticated: 100/min
}
return Limit::perMinute(20)->by($request->ip()); // Anonymous: 20/min
});
// Login limiter to prevent brute force
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)
->by($request->ip()) // Key by IP address
->response(function () { // Custom exceeded response
return response()->json([
'message' => 'Too many login attempts. Try again in a minute.',
], 429);
});
});
}A aplicação de limiters nomeados às rotas utiliza a sintaxe throttle:name:
Route::middleware('throttle:api')->group(function () {
Route::apiResource('/posts', PostController::class);
});
// routes/web.php
Route::middleware('throttle:login')
->post('/login', [AuthController::class, 'login']);O rate limiter escalonado acima demonstra um padrão de produção: usuários enterprise obtêm limites mais altos, usuários autenticados recebem limites moderados, e requisições anônimas são restringidas de forma agressiva. O método by() determina a chave de limitação — usando o ID do usuário para usuários autenticados e o endereço IP como fallback.
Pronto para mandar bem nas entrevistas de Laravel?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Criando middleware personalizado do zero
A criação de middleware personalizado cobre cenários que os middleware integrados não tratam. O comando Artisan make:middleware gera uma nova classe com a estrutura correta.
php artisan make:middleware EnsureUserHasRoleMiddleware de controle de acesso baseado em papéis
Um padrão comum de middleware personalizado aplica autorização baseada em papéis no nível da rota, aceitando nomes de papéis como parâmetros.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string ...$roles): Response
{
$user = $request->user();
if (! $user || ! $user->hasAnyRole($roles)) {
abort(403, 'Insufficient permissions.');
}
return $next($request);
}
}O parâmetro variádico ...$roles permite passar múltiplos papéis separados por vírgulas. O registro e a utilização ficam assim:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \App\Http\Middleware\EnsureUserHasRole::class,
]);
})
// routes/web.php
Route::middleware('role:admin')->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
Route::resource('/articles', ArticleController::class);
});Middleware de transformação de requisições
Um middleware pode modificar a requisição antes que ela alcance o controller. A seguir, um middleware para API JSON que impõe cabeçalhos de tipo de conteúdo e limpa as entradas do tipo string:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ApiRequestSanitizer
{
public function handle(Request $request, Closure $next): Response
{
// Reject non-JSON requests on API routes
if (! $request->expectsJson() && $request->isMethod('POST')) {
return response()->json(
['error' => 'Content-Type must be application/json'],
415
);
}
// Trim all string inputs
$input = $request->all();
array_walk_recursive($input, function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
});
$request->merge($input);
return $next($request);
}
}Esse middleware cuida de duas responsabilidades: valida o tipo de conteúdo para requisições POST e sanitiza todas as entradas de texto removendo espaços em branco desnecessários.
Registro de middleware no Laravel 12
O Laravel 12 centraliza todo o registro de middleware no arquivo bootstrap/app.php. Essa abordagem substituiu o antigo app/Http/Kernel.php que existia antes do Laravel 11.
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
// Global middleware (runs on every request)
$middleware->append(
\App\Http\Middleware\LogRequestTime::class
);
// Add to the 'web' middleware group
$middleware->web(append: [
\App\Http\Middleware\TrackPageViews::class,
]);
// Add to the 'api' middleware group
$middleware->api(prepend: [
\App\Http\Middleware\ApiRequestSanitizer::class,
]);
// Register aliases for route-level use
$middleware->alias([
'role' => \App\Http\Middleware\EnsureUserHasRole::class,
'subscribed' => \App\Http\Middleware\EnsureUserIsSubscribed::class,
]);
// Control execution order
$middleware->priority([
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\App\Http\Middleware\EnsureUserHasRole::class,
]);
})
->create();O array priority é importante quando múltiplos middleware são atribuídos à mesma rota. O Laravel os ordena de acordo com essa lista, garantindo que a sessão seja iniciada antes da autenticação, e que a autenticação seja concluída antes das verificações de papel.
Os middleware são executados na ordem de registro. Para middleware de rota, o array priority sobrescreve a ordem padrão. A autenticação deve ser sempre posicionada antes da autorização para evitar verificar papéis em requisições não autenticadas.
Middleware terminável para tarefas pós-resposta
O middleware terminável executa lógica após a resposta ter sido enviada ao cliente. Isso é particularmente útil para tarefas de logging, analytics ou limpeza que não devem bloquear o usuário.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;
class CollectAnalytics
{
public function handle(Request $request, Closure $next): Response
{
return $next($request); // Pass through without delay
}
public function terminate(Request $request, Response $response): void
{
// Runs after response is sent to client
DB::table('analytics')->insert([
'path' => $request->path(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'created_at' => now(),
]);
}
}O método terminate recebe tanto a requisição original quanto a resposta final. Recomenda-se registrar esse middleware como singleton no AppServiceProvider para garantir que a mesma instância trate tanto handle() quanto terminate().
Padrões de middleware para produção
Diversos padrões de middleware aparecem consistentemente em aplicações Laravel em produção.
Bypass do modo de manutenção — permitir que IPs internos acessem a aplicação durante a manutenção:
class MaintenanceBypass
{
private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];
public function handle(Request $request, Closure $next): Response
{
if (app()->isDownForMaintenance()) {
foreach ($this->allowedIps as $ip) {
if ($request->ip() === $ip) {
return $next($request);
}
}
}
return $next($request);
}
}Cabeçalhos de segurança — adicionar HSTS, política de segurança de conteúdo e outros cabeçalhos a cada resposta:
class SecurityHeaders
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains'
);
return $response;
}
}Esses padrões ilustram as duas posições principais dos middleware: antes da requisição (o bypass de manutenção verifica o IP e potencialmente bloqueia o acesso) e depois da resposta (os cabeçalhos de segurança modificam a resposta de saída).
Pronto para mandar bem nas entrevistas de Laravel?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Conclusão
- O middleware do Laravel opera como um pipeline: cada classe processa a requisição, atua sobre ela e a passa adiante ou interrompe o fluxo com uma resposta
- O middleware
authprotege rotas com autenticação baseada em guards, suportando múltiplos tipos de usuários via sintaxeauth:guard - A limitação de taxa através do middleware
throttlee das definições nomeadasRateLimiter::for()permite controle de acesso escalonado com base no contexto do usuário - Os middleware personalizados tratam preocupações transversais como verificações de papel, sanitização de requisições e cabeçalhos de segurança sem sobrecarregar os controllers
- Todo o registro de middleware no Laravel 12 acontece em
bootstrap/app.phpusando uma API fluente, comprioritycontrolando a ordem de execução - O middleware terminável executa tarefas pós-resposta (analytics, logging) sem impactar a latência percebida pelo usuário
- Os parâmetros de middleware via sintaxe
:parammantêm as definições de rota expressivas e as classes middleware reutilizáveis em diferentes contextos
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Tags
Compartilhar
Artigos relacionados

Perguntas de Entrevista sobre Laravel e PHP: As 25 Principais em 2026
As 25 perguntas mais comuns em entrevistas sobre Laravel e PHP. Eloquent ORM, middleware, artisan, filas, testes e arquitetura com respostas detalhadas e exemplos de codigo.

Laravel 11: Construindo uma Aplicacao Completa do Zero
Guia completo para construir uma aplicacao com Laravel 11: autenticacao, API REST, Eloquent ORM e deploy em producao. Tutorial pratico para desenvolvedores iniciantes e intermediarios.

Symfony 7: API Platform e Boas Praticas
Guia completo para criar APIs REST profissionais com Symfony 7 e API Platform 4. State Providers, Processors, validacao e serializacao explicados com exemplos praticos.