Что можно сделать с помощью middleware в Laravel
Вот тут-то и приходит на помощь middleware. Думайте о нём как о «вышибале» в приложении — он проверяет, изменяет или отклоняет запросы до того, как они попадут к контроллерам. Или даже после того, как запрос обработан (многие об этом не знают). Вместо того чтобы загромождать контроллеры повторяющейся логикой или разделять эту логику в трейте, middleware помогает добавлять функциональность по нескольким маршрутам более чистым и удобным способом.
Почему middleware важно
Настоящая сила middleware заключается не только в чистых контроллерах, но и в том, когда выполняется код:
- Если поместить проверки в
__construct()
, то контроллер уже будет инстанцирован до их выполнения. - С middleware проверка происходит ещё до обращения к контроллеру, что полностью его защищает.
Так когда следует создавать middleware? Давайте разберёмся.
Как создать middleware (краткое руководство)
Прежде чем перейти к примерам, давайте посмотрим, как создать и применить middleware, чтобы вы точно знали, где находится код.
Генерация middleware:
php artisan make:middleware YourMiddlewareName
Это создаст файл
app/Http/Middleware/YourMiddlewareName.php
, в котором будет прописана логика.Использование middleware:
Теперь его можно применить к маршрутам следующим образом:
Route::get('/some-route', 'SomeController@index')->middleware(YourMiddlewareName::class);
Хорошо, теперь, когда известно, куда помещать код, давайте разберёмся, когда следует создавать middleware.
Когда следует создавать middleware (с примерами)
Собственные проверки аутентификации
Встроенная в Laravel аутентификация — это прекрасно, но иногда необходимы дополнительные проверки. Возможно, необходимо разрешить доступ только верифицированным пользователям или ограничить доступ на основе ролей, разрешений или планов подписки.
Пример: Только премиум-пользователи могут получить доступ к определённым страницам
public function handle(Request $request, Closure $next)
{
if (!$request->user() || !$request->user()->is_premium) {
return redirect('/upgrade');
}
return $next($request);
}
Как использовать:
Route::get('/premium-content', function () {
return view('premium');
})->middleware('checkPremiumUser');
Теперь доступ к этой странице получают только премиум-пользователи.
Автоматическое журналирование запросов
Требуется отслеживать входящие запросы для аналитики или отладки? Middleware позволяет регистрировать детали запросов, не загромождая контроллеры.
Пример: Регистрация каждого посещённого URL с временной меткой
public function handle(Request $request, Closure $next)
{
\Log::info('User visited: ' . $request->url());
$request->user()?->update(['last_seen' => now()]);
return $next($request);
}
Как использовать:
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('trackActivity');
Теперь каждый визит автоматически регистрируется!
Очистка и модификация вводимых данных до их передачи контроллерам
Изменяйте или экранируйте вводимые пользователем данные до их обработки. Это отлично подходит для обеспечения согласованности данных в приложении.
Пример: Преобразование всех вводимых адресов электронной почты в нижний регистр
public function handle(Request $request, Closure $next)
{
if ($request->has('email')) {
$request->merge(['email' => strtolower($request->email)]);
}
return $next($request);
}
Как использовать:
Route::post('/register', 'AuthController@register')->middleware('normalizeEmail');
Теперь все адреса электронной почты автоматически преобразуются в нижний регистр.
Ограничение доступа (белый список IP-адресов, режим обслуживания)
Необходимо временно заблокировать пользователей на время выполнения обновлений, но сохранить доступ для определённых IP-адресов (например, команды разработчиков).
Пример: Разрешить доступ только пользователям с определённого IP-адреса
public function handle(Request $request, Closure $next)
{
$allowedIps = ['123.456.789.1']; // Замените на IP-адрес вашего офиса
if (!in_array($request->ip(), $allowedIps)) {
return response('Site is under maintenance', 503);
}
return $next($request);
}
Как использовать:
Route::get('/admin', function () {
return view('admin.dashboard');
})->middleware('restrictByIp');
Теперь только разрешённые IP-адреса могут получить доступ к панели администрирования.
Автоматическое переключение языка
Хотите переключать язык приложения в зависимости от пользовательского запроса? Middleware может обнаружить параметр запроса lang
и установить язык автоматически.
Пример: Если пользователь заходит на /?lang=fr
, приложение переключается на французский язык.
public function handle(Request $request, Closure $next)
{
if ($request->has('lang')) {
app()->setLocale($request->lang);
}
return $next($request);
}
Как использовать:
Route::get('/', function () {
return view('welcome');
})->middleware('setLanguage');
Теперь приложение автоматически задаёт язык в зависимости от параметра URL.
Выполнение действия после запроса
Middleware используется не только перед запросами — оно может выполняться и после отправки ответа. Это удобно для таких задач, как ведение логов, очистки или изменения ответа перед его отправкой обратно пользователю.
Пример: Ведение логов времени отклика для мониторинга производительности
Необходимо измерить, сколько времени занимает обработка запроса? Middleware может отслеживать это время и протоколировать его для получения информации о производительности.
public function handle(Request $request, Closure $next)
{
$start = microtime(true); // Запись времени старта
$response = $next($request);
$duration = microtime(true) - $start; // Вычисление времени выполнения
\Log::info("Request to {$request->path()} took {$duration} seconds");
return $response;
}
Теперь каждый запрос будет регистрировать время его выполнения, что поможет обнаружить медленные конечные точки.
Заключение
Если вы повторяете одну и ту же логику в нескольких контроллерах, остановитесь прямо сейчас. Middleware создано именно для этого. Ваши контроллеры должны быть сосредоточены на реальной бизнес-логике, а не на случайных повторяющихся задачах — middleware обеспечивает этот процесс.
Так что в следующий раз, когда подумаете: Это нужно сделать до или после каждого запроса
, — это сигнал к созданию middleware!