# 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. - Published: 2026-04-16 - Updated: 2026-04-16 - Author: SharpSkill - Tags: laravel, middleware, authentication, rate-limiting, php - Reading time: 10 min --- 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. > **Middleware em resumo** > > 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. ```php // app/Http/Middleware/LogRequestTime.php 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). ```php // routes/web.php 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](/technologies/laravel/interview-questions/authentication). O middleware `auth` aceita um parâmetro de guard para especificar qual driver de autenticação deve ser utilizado. ```php // routes/api.php // 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. > **Middleware Guest** > > 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. ```php // routes/api.php // 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. ```php // app/Providers/AppServiceProvider.php 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`: ```php // routes/api.php 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. ## Criando middleware personalizado do zero A criação de [middleware](/technologies/laravel/interview-questions/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. ```bash php artisan make:middleware EnsureUserHasRole ``` ### Middleware de controle de acesso baseado em papéis Um padrão comum de middleware personalizado aplica [autorização baseada em papéis](/technologies/laravel/interview-questions/authorization-policies) no nível da rota, aceitando nomes de papéis como parâmetros. ```php // app/Http/Middleware/EnsureUserHasRole.php 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: ```php // bootstrap/app.php ->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: ```php // app/Http/Middleware/ApiRequestSanitizer.php 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. ```php // bootstrap/app.php 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. > **Ordem de execução dos middleware** > > 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. ```php // app/Http/Middleware/CollectAnalytics.php 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](/blog/laravel/laravel-11-building-complete-application) em produção. **Bypass do modo de manutenção** — permitir que IPs internos acessem a aplicação durante a manutenção: ```php // app/Http/Middleware/MaintenanceBypass.php 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: ```php // app/Http/Middleware/SecurityHeaders.php 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). ## 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 `auth` protege rotas com autenticação baseada em guards, suportando múltiplos tipos de usuários via sintaxe `auth:guard` - A limitação de taxa através do middleware `throttle` e das definições nomeadas `RateLimiter::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.php` usando uma API fluente, com `priority` controlando 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 `:param` mantêm as definições de rota expressivas e as classes middleware reutilizáveis em diferentes contextos --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/laravel/laravel-middleware-deep-dive