Laravel Middleware: Автентифікація, Rate Limiting та власні middleware
Вичерпний посібник з middleware у Laravel з практичними прикладами: guard автентифікації, rate limiting з throttle, створення власних middleware, PHP-атрибути в Laravel 13 та просунуті патерни для продакшен-застосунків.

Middleware у Laravel виконує роль фільтрувального шару між вхідними HTTP-запитами та логікою застосунку. Кожен запит проходить через конвеєр класів middleware перш ніж потрапити до контролера, і кожна відповідь повертається тим самим шляхом. Розуміння цього механізму є критично важливим для побудови безпечних та продуктивних Laravel-застосунків.
Middleware перехоплює HTTP-запити до того, як вони досягнуть маршрутів. Laravel реєструє всі middleware у файлі bootstrap/app.php за допомогою fluent API. Вбудовані middleware забезпечують автентифікацію, захист від CSRF, керування сесіями та rate limiting одразу після встановлення.
Як працює конвеєр middleware у Laravel
HTTP-ядро Laravel обробляє кожен запит через стек middleware. Кожен middleware отримує запит, виконує свою логіку, а потім передає запит до наступного шару через $next($request) або перериває конвеєр, повертаючи відповідь безпосередньо.
Ця архітектура реалізує патерн Chain of Responsibility (Ланцюг відповідальності). Middleware може діяти до того, як запит досягне контролера (наприклад, перевірка автентифікації), після генерації відповіді (наприклад, додавання заголовків) або в обох випадках одночасно.
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).
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. Middleware auth приймає параметр guard, який визначає, який драйвер автентифікації використовувати.
// 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 є протилежністю auth, пропускає лише неавтентифікованих користувачів. Застосування його до маршрутів входу та реєстрації запобігає повторному доступу вже автентифікованих користувачів до цих сторінок.
Rate Limiting з Throttle Middleware
Rate limiting у Laravel захищає маршрути від зловживань за допомогою вбудованого middleware throttle. Найпростіша форма приймає два параметри: максимальну кількість запитів та часове вікно в хвилинах.
// 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. Додаткові опції описані в офіційній документації rate limiting.
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:назва:
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-адресу як запасний варіант.
Готовий до співбесід з Laravel?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Створення власних middleware з нуля
Створення власних middleware охоплює сценарії, які вбудовані middleware не обробляють. Artisan-команда make:middleware генерує новий клас із правильною структурою.
php artisan make:middleware EnsureUserHasRoleMiddleware контролю доступу на основі ролей
Поширений патерн власного middleware забезпечує авторизацію на основі ролей на рівні маршруту, приймаючи назви ролей як параметри.
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 дозволяє передавати кілька ролей, розділених комами. Реєстрація та використання виглядають наступним чином:
->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 та обрізає рядкові дані:
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 в bootstrap/app.php
Laravel централізує всю реєстрацію middleware у файлі bootstrap/app.php. Це замінило старший підхід з файлом app/Http/Kernel.php, який існував до Laravel 11. Той самий fluent API працює в Laravel 12 та 13.
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 на рівні маршруту масив priority перевизначає порядок за замовчуванням. Автентифікацію слід завжди розміщувати перед авторизацією, щоб уникнути перевірки ролей для неавтентифікованих запитів.
PHP-атрибути для middleware в Laravel 13
Laravel 13 представив PHP-атрибут #[Middleware] для оголошення middleware безпосередньо на класах контролерів та методах. Цей підхід зберігає конфігурацію middleware поруч із кодом, який вона захищає, що полегшує читання та підтримку правил авторизації.
namespace App\Http\Controllers;
use App\Models\Comment;
use App\Models\Post;
use Illuminate\Routing\Attributes\Controllers\Authorize;
use Illuminate\Routing\Attributes\Controllers\Middleware;
#[Middleware('auth')]
class CommentController
{
#[Middleware('subscribed')]
#[Authorize('create', [Comment::class, 'post'])]
public function store(Post $post)
{
// Only authenticated, subscribed users who can create comments reach here
}
public function index(Post $post)
{
// Still requires auth (from class-level attribute)
return $post->comments;
}
}Атрибут #[Middleware('auth')] на рівні класу застосовується до всіх методів. Атрибути на рівні методів накладаються: store() вимагає як auth, так і subscribed. Атрибут #[Authorize] інтегрується з системою політик Laravel, перевіряючи дозволи перед виконанням методу.
Цей підхід на основі атрибутів є опціональним. Middleware у файлах маршрутів та реєстрація в bootstrap/app.php залишаються повністю підтримуваними. Команди, які віддають перевагу явним визначенням маршрутів, можуть продовжувати використовувати fluent API; команди, які хочуть самодокументовані контролери, можуть застосовувати атрибути.
Terminable Middleware для завдань після відповіді
Terminable middleware виконує логіку після відправлення відповіді клієнту. Це корисно для логування, аналітики або задач очищення, які не повинні блокувати користувача.
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-застосунках.
Обхід режиму обслуговування дозволяє внутрішнім IP-адресам отримувати доступ до застосунку під час обслуговування:
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, політику безпеки контенту та інші заголовки до кожної відповіді:
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 та потенційно блокує) та після відповіді (заголовки безпеки модифікують вихідну відповідь).
Готовий до співбесід з Laravel?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Джерела
- Документація Laravel Middleware - Офіційний довідник з реєстрації middleware, груп та параметрів
- Laravel 13 Release Notes - Анонс атрибуту
#[Middleware]та покращеньPreventRequestForgery - Документація Laravel Rate Limiting - Фасад RateLimiter, іменовані limiter та конфігурація throttle middleware
Патерни middleware Laravel для підготовки до співбесіди
- Middleware у Laravel працює як конвеєр: кожен клас обробляє запит, виконує над ним дії та передає далі або перериває ланцюг, повертаючи відповідь
- Middleware
authзахищає маршрути за допомогою автентифікації на основі guard, підтримуючи кілька типів користувачів через синтаксисauth:guard - Rate limiting через middleware
throttleта іменовані визначенняRateLimiter::for()забезпечує багаторівневий контроль доступу на основі контексту користувача - Власні middleware обробляють наскрізні аспекти, перевірку ролей, санітизацію запитів, заголовки безпеки, без засмічення контролерів
- Уся реєстрація middleware відбувається у
bootstrap/app.phpза допомогою fluent API, а масивpriorityконтролює порядок виконання - Атрибут
#[Middleware]у Laravel 13 дозволяє оголошувати middleware безпосередньо на контролерах, зберігаючи правила авторизації поруч із обробниками - Terminable middleware виконує задачі після відповіді (аналітика, логування) без впливу на затримку для користувача
- Параметри middleware через синтаксис
:paramзберігають визначення маршрутів виразними, а класи middleware, придатними для повторного використання в різних контекстах
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
Чи знайдеш ти помилку в Laravel?
Справжній фрагмент коду, прихована помилка, одна спроба на день. Щоб спробувати, акаунт не потрібен.

Автор:
Anthony Fillion-MailletЗасновник SharpSkill
Fullstack-розробник понад 10 років. Керує SharpSkill і відповідає за все, що тут публікується.
Оновлено 21 вересня 2026 р.
Теги
Поділитися
Пов'язані статті

Питання на співбесіду PHP Laravel Developer 2026: Повний посібник з підготовки
Комплексний посібник з технічних питань на співбесіду для PHP Laravel розробників у 2026 році. Охоплює Eloquent ORM, Service Container, авторизацію, черги та тестування.

Laravel 12 у 2026 році: нові можливості, Starter Kits та питання для співбесіди
Повний огляд Laravel 12: перероблені Starter Kits на основі React 19, Vue 3, Svelte 5 та Livewire 4, інтеграція WorkOS AuthKit, оновлення залежностей до Carbon 3 та PHP 8.2+, покроковий посібник з оновлення з Laravel 11 та актуальні питання для технічних співбесід у 2026 році.

Рішення Laravel: Розширені Патерни, Налагодження та Питання на Співбесіді 2026
Комплексний посібник з розширених архітектурних патернів Laravel, технік налагодження з Telescope та найпоширеніших питань на співбесідах для розробників Laravel.