# Laravel Middleware: Поглиблений огляд автентифікації, Rate Limiting та власних middleware > Вичерпний посібник з middleware у Laravel — від автентифікації та rate limiting до створення власних класів middleware. Практичні приклади коду та патерни для продакшену. - Published: 2026-04-16 - Updated: 2026-04-16 - Author: SharpSkill - Tags: laravel, middleware, php, authentication, rate-limiting - Reading time: 8 min --- Middleware у Laravel виконує роль фільтрувального шару між вхідними HTTP-запитами та логікою застосунку. Кожен запит проходить через конвеєр класів middleware перш ніж потрапити до контролера, і кожна відповідь повертається тим самим шляхом. Розуміння цього механізму є критично важливим для побудови безпечних та продуктивних Laravel-застосунків у 2026 році. > **Middleware коротко** > > Middleware перехоплює HTTP-запити до того, як вони досягнуть маршрутів. Laravel 12 реєструє всі middleware у файлі `bootstrap/app.php` за допомогою fluent API. Вбудовані middleware забезпечують автентифікацію, захист від CSRF, керування сесіями та rate limiting одразу після встановлення. ## Як працює конвеєр middleware у Laravel HTTP-ядро Laravel обробляє кожен запит через стек middleware. Кожен middleware отримує запит, виконує свою логіку, а потім передає запит до наступного шару через `$next($request)` або перериває конвеєр, повертаючи відповідь безпосередньо. Ця архітектура реалізує патерн Chain of Responsibility (Ланцюг відповідальності). Middleware може діяти **до** того, як запит досягне контролера (наприклад, перевірка автентифікації), **після** генерації відповіді (наприклад, додавання заголовків) або в обох випадках одночасно. ```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 } } ``` Цей middleware обгортає запит: фіксує час початку **до** обробки та логує тривалість **після** повернення відповіді. Цей патерн до/після є центральним принципом роботи middleware. ## Middleware автентифікації: Захист маршрутів Laravel постачається з аліасом middleware `auth`, який відповідає `Illuminate\Auth\Middleware\Authenticate`. Застосування його до маршруту гарантує, що лише автентифіковані користувачі зможуть отримати доступ. Неавтентифіковані користувачі отримують відповідь 401 (API) або перенаправляються на сторінку входу (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']); }); ``` ### Автентифікація з кількома Guard Застосунки з кількома типами користувачів (адмін-панель, клієнтська зона, API) використовують [автентифікацію на основі guard](/technologies/laravel/interview-questions/authentication). Middleware `auth` приймає параметр guard, який визначає, який драйвер автентифікації використовувати. ```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']); }); ``` Параметр guard після двокрапки вказує Laravel, проти якої конфігурації автентифікації виконувати перевірку. Це дозволяє зберігати логіку автентифікації чистою та розділеною між різними частинами застосунку. > **Middleware Guest** > > Middleware `guest` є протилежністю `auth` — пропускає лише неавтентифікованих користувачів. Застосування його до маршрутів входу та реєстрації запобігає повторному доступу вже автентифікованих користувачів до цих сторінок. ## Rate Limiting з Throttle Middleware Rate limiting у Laravel захищає маршрути від зловживань за допомогою вбудованого middleware `throttle`. Найпростіша форма приймає два параметри: максимальну кількість запитів та часове вікно в хвилинах. ```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 Limiter для розширеного контролю Визначення іменованих rate limiter у `AppServiceProvider` надає точний контроль над лімітами залежно від контексту користувача. Цей підхід значно гнучкіший за inline-параметри throttle. ```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); }); }); } ``` Застосування іменованих limiter до маршрутів використовує синтаксис `throttle:назва`: ```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']); ``` Багаторівневий rate limiter вище демонструє продакшен-патерн: enterprise-користувачі отримують вищі ліміти, автентифіковані користувачі — помірні, а анонімні запити обмежуються агресивно. Метод `by()` визначає ключ rate limit — ідентифікатор користувача для автентифікованих та IP-адресу як запасний варіант. ## Створення власних middleware з нуля Створення власних [middleware](/technologies/laravel/interview-questions/middleware) охоплює сценарії, які вбудовані middleware не обробляють. Artisan-команда `make:middleware` генерує новий клас із правильною структурою. ```bash php artisan make:middleware EnsureUserHasRole ``` ### Middleware контролю доступу на основі ролей Поширений патерн власного middleware забезпечує [авторизацію на основі ролей](/technologies/laravel/interview-questions/authorization-policies) на рівні маршруту, приймаючи назви ролей як параметри. ```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); } } ``` Варіативний параметр `...$roles` дозволяє передавати кілька ролей, розділених комами. Реєстрація та використання виглядають наступним чином: ```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 трансформації запитів Middleware може модифікувати запит перш ніж він досягне контролера. Приклад middleware для JSON API, що перевіряє заголовки content type та обрізає рядкові дані: ```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); } } ``` Цей middleware обробляє два аспекти: валідує тип контенту для POST-запитів та санітизує всі рядкові вхідні дані, видаляючи пробіли. ## Реєстрація middleware у Laravel 12 Laravel 12 централізує всю реєстрацію middleware у файлі `bootstrap/app.php`. Це замінило старший підхід з файлом `app/Http/Kernel.php`, який існував до 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(); ``` Масив `priority` має значення, коли до одного маршруту призначено кілька middleware. Laravel сортує їх відповідно до цього списку, гарантуючи запуск сесії перед автентифікацією, а автентифікації — перед перевіркою ролей. > **Порядок виконання middleware** > > Middleware виконується в порядку реєстрації. Для middleware на рівні маршруту масив `priority` перевизначає порядок за замовчуванням. Автентифікацію слід завжди розміщувати перед авторизацією, щоб уникнути перевірки ролей для неавтентифікованих запитів. ## Terminable Middleware для завдань після відповіді Terminable middleware виконує логіку **після** відправлення відповіді клієнту. Це корисно для логування, аналітики або задач очищення, які не повинні блокувати користувача. ```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(), ]); } } ``` Метод `terminate` отримує як оригінальний запит, так і фінальну відповідь. Middleware слід зареєструвати як singleton у `AppServiceProvider`, щоб гарантувати, що той самий екземпляр обробляє як `handle()`, так і `terminate()`. ## Практичні патерни middleware для продакшену Кілька патернів middleware послідовно з'являються у продакшен [Laravel-застосунках](/blog/laravel/laravel-11-building-complete-application). **Обхід режиму обслуговування** — дозволяє внутрішнім IP-адресам отримувати доступ до застосунку під час обслуговування: ```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); } } ``` **Заголовки безпеки** — додає HSTS, політику безпеки контенту та інші заголовки до кожної відповіді: ```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; } } ``` Ці патерни демонструють дві основні позиції middleware: **до** запиту (обхід обслуговування перевіряє IP та потенційно блокує) та **після** відповіді (заголовки безпеки модифікують вихідну відповідь). ## Висновок - Middleware у Laravel працює як конвеєр: кожен клас обробляє запит, виконує над ним дії та передає далі або перериває ланцюг, повертаючи відповідь - Middleware `auth` захищає маршрути за допомогою автентифікації на основі guard, підтримуючи кілька типів користувачів через синтаксис `auth:guard` - Rate limiting через middleware `throttle` та іменовані визначення `RateLimiter::for()` забезпечує багаторівневий контроль доступу на основі контексту користувача - Власні middleware обробляють наскрізні аспекти — перевірку ролей, санітизацію запитів, заголовки безпеки — без засмічення контролерів - Уся реєстрація middleware у Laravel 12 відбувається у `bootstrap/app.php` за допомогою fluent API, а масив `priority` контролює порядок виконання - Terminable middleware виконує задачі після відповіді (аналітика, логування) без впливу на затримку для користувача - Параметри middleware через синтаксис `:param` зберігають визначення маршрутів виразними, а класи middleware — придатними для повторного використання в різних контекстах --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/laravel/laravel-middleware-deep-dive