Что можно сделать с помощью middleware в Laravel

Вам приходилось писать одни и те же проверки в нескольких контроллерах? Например, форматирование вводимых данных, блокировка доступа или отслеживание пользовательской активности? Всё это начинает казаться повторяющимся, верно?... и быстро надоедает.

Вот тут-то и приходит на помощь middleware. Думайте о нём как о «вышибале» в приложении — он проверяет, изменяет или отклоняет запросы до того, как они попадут к контроллерам. Или даже после того, как запрос обработан (многие об этом не знают). Вместо того чтобы загромождать контроллеры повторяющейся логикой или разделять эту логику в трейте, middleware помогает добавлять функциональность по нескольким маршрутам более чистым и удобным способом.

Почему middleware важно

Настоящая сила middleware заключается не только в чистых контроллерах, но и в том, когда выполняется код:

Так когда следует создавать middleware? Давайте разберёмся.

Как создать middleware (краткое руководство)

Прежде чем перейти к примерам, давайте посмотрим, как создать и применить middleware, чтобы вы точно знали, где находится код.

  1. Генерация middleware:

    php artisan make:middleware YourMiddlewareName

    Это создаст файл app/Http/Middleware/YourMiddlewareName.php, в котором будет прописана логика.

  2. Использование 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!

Комментарии


Дополнительные материалы

Предыдущая Статья

Шаблоны повышения производительности Eloquent