Middleware: фильтры запросов
Middleware — это слои-фильтры, через которые проходит каждый запрос на пути к контроллеру и ответ на пути обратно.
Суть: middleware проверяет или изменяет запрос до контроллера (авторизация, CSRF) и ответ после (заголовки, кэш). В Laravel 11 они регистрируются в
bootstrap/app.php.
Представьте проходную в офис: прежде чем попасть к рабочему месту, вы показываете пропуск охраннику, проходите рамку, регистрируетесь. Middleware — это те самые «проходные» для HTTP-запросов. Прежде чем запрос дойдёт до контроллера, он проходит цепочку фильтров: проверяется аутентификация, валидируется CSRF-токен, стартует сессия. А ответ на пути обратно тоже проходит фильтры — например, добавляются заголовки безопасности.
Laravel из коробки даёт множество middleware: auth (пускает только авторизованных), guest (только гостей), throttle (ограничивает частоту запросов), проверку CSRF. Вы можете писать и свои — например, проверку роли «администратор».
Как работает под капотом: модель «луковицы»
Middleware работают по принципу луковицы (onion): запрос проходит слои внутрь до контроллера, а ответ выходит наружу через те же слои в обратном порядке.
ВХОД (запрос)
+---------------------------+
| StartSession |
| +---------------------+ |
| | VerifyCsrfToken | |
| | +---------------+ | |
| | | Authenticate | | |
| | | +---------+ | | |
| | | |CONTROLLER| | | |
| | | +---------+ | | |
| | +---------------+ | |
| +---------------------+ |
+---------------------------+
ВЫХОД (ответ)
Каждый middleware решает: пропустить запрос дальше (вызвать $next) или остановить его — например, перенаправить гостя на страницу логина.
Создание своего middleware
php artisan make:middleware EnsureUserIsAdmin<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureUserIsAdmin
{
public function handle(Request $request, Closure $next)
{
if (! $request->user()?->is_admin) {
abort(403, 'Доступ только для администраторов');
}
// пропускаем запрос дальше по цепочке
return $next($request);
}
}В Laravel 11 псевдонимы middleware регистрируются в bootstrap/app.php:
<?php
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
]);
})А применяется middleware к маршрутам через ->middleware():
<?php
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware(['auth', 'admin']);Смоделируем цепочку middleware на Python — каждый фильтр либо пропускает запрос, либо останавливает его.
Попробуй сам ▶
# Цепочка middleware (модель луковицы)
def check_auth(request, nxt):
if not request.get('logged_in'):
return '302 -> /login'
return nxt(request)
def check_admin(request, nxt):
if not request.get('is_admin'):
return '403 Forbidden'
return nxt(request)
def controller(request):
return '200 OK: панель администратора'
def run(request, stack, ctrl):
def chain(i):
if i == len(stack):
return ctrl(request)
return stack[i](request, lambda r: chain(i + 1))
return chain(0)
stack = [check_auth, check_admin]
print(run({'logged_in': True, 'is_admin': True}, stack, controller))
print(run({'logged_in': True, 'is_admin': False}, stack, controller))
print(run({'logged_in': False}, stack, controller))
Частые ошибки
- Забыть
return $next($request). Без этого запрос не дойдёт до контроллера и зависнет. - Тяжёлая логика в middleware. Middleware должны быть быстрыми фильтрами, а не местом для бизнес-логики.
- Неверный порядок. Например, проверка роли до проверки аутентификации — пользователь ещё не известен.
Best practices
- Применяйте middleware группами через
Route::middleware([...])->group(). - Держите каждый middleware маленьким и с одной зоной ответственности.
- Используйте встроенные
auth,throttle,verifiedвместо самописных, где можно.
Итог: middleware — это конвейер фильтров вокруг контроллера, реализующий сквозные задачи: авторизацию, защиту, ограничения. Дальше переходим к слою представления — шаблонизатору Blade.