Middleware и защита маршрутов

Рейтинг: 49% · 10 голосов
Курс по Laravel: маршруты, Eloquent, Blade, миграции, очереди и API. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
oleg_php
Сообщения: 25
Зарегистрирован: 14 май 2026, 08:06

Middleware и защита маршрутов

Сообщение oleg_php »

АкадемияLaravel с нуляГлава 9 из 18
Оглавление курса (18)
  1. Знакомство с Laravel и установка окружения
  2. Маршруты и контроллеры
  3. Blade: шаблоны и вёрстка страниц
  4. Миграции и структура базы данных
  5. Eloquent ORM: модели и CRUD
  6. Связи в Eloquent: hasMany, belongsTo и другие
  7. Формы и валидация данных
  8. Аутентификация пользователей
  9. Middleware и защита маршрутов (вы здесь)
  10. Очереди и фоновые задачи
  11. Отправка почты и уведомления
  12. Строим REST API на Laravel
  13. Авторизация: Gates и Policies
  14. Работа с файлами: загрузка, Storage, диски local и S3
  15. Тестирование: Pest и PHPUnit, фабрики, сидеры, RefreshDatabase
  16. Сервис-контейнер, провайдеры, свои artisan-команды и планировщик
  17. Деплой в продакшен и обзор современного фронтенда (Vite, Livewire, Inertia)
  18. События и слушатели, кеширование, логирование
В прошлой главе мы научили приложение узнавать пользователя. Теперь надо научить его не пускать кого попало в админку и другие закрытые разделы. Для этого в Laravel есть middleware: слой, через который проходит каждый HTTP-запрос до того, как доберется до контроллера.

Как это устроено:

Представьте конвейер. Запрос входит в приложение и проходит через цепочку middleware: один проверяет CSRF-токен, другой стартует сессию, третий смотрит, авторизован ли пользователь. Каждый слой может пропустить запрос дальше, что-то в нем поменять или оборвать обработку и сразу вернуть ответ. Готовый ответ потом идет через ту же цепочку в обратном порядке.

Вы уже пользовались middleware, даже если не заметили: проверка CSRF-токена в формах из главы 7 и редирект гостей на страницу логина из главы 8 работают именно так.

Пишем свое middleware:

Допустим, у пользователей есть булева колонка is_admin (добавили миграцией), и админка должна быть закрыта для всех остальных. Генерируем класс:

Код: Выделить всё

php artisan make:middleware EnsureUserIsAdmin
Файл появится в app/Http/Middleware/EnsureUserIsAdmin.php. Вся логика живет в методе handle:

Код: Выделить всё

public function handle(Request $request, Closure $next): Response
{
    if (! $request->user() || ! $request->user()->is_admin) {
        abort(403, 'Только для администраторов');
    }

    return $next($request);
}
Вызов $next($request) передает запрос дальше по цепочке. Все, что вы напишете до него, выполнится до контроллера. Если код стоит после вызова, он отработает уже на готовом ответе, так делают логирование или добавление заголовков. Метод обязан вернуть Response, поэтому строка return $next($request) не украшение, а суть.

Регистрация и подключение:

Начиная с Laravel 11 middleware регистрируют в bootstrap/app.php. Файла app/Http/Kernel.php в новых проектах больше нет, в Laravel 10 и старше ищите его. Дадим классу короткий псевдоним:

Код: Выделить всё

->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
    ]);
})
Теперь вешаем его на маршруты. Удобнее всего группой:

Код: Выделить всё

Route::middleware(['auth', 'admin'])
    ->prefix('admin')
    ->group(function () {
        Route::get('/', [AdminController::class, 'index'])->name('admin.home');
        Route::resource('posts', AdminPostController::class);
    });
Порядок в массиве имеет значение: сначала auth отправит гостя на логин, и только залогиненный пользователь дойдет до нашей проверки is_admin.

Middleware умеют принимать параметры: добавьте в handle аргумент string $role и подключайте как 'role:editor'. Это спасает, когда ролей несколько и плодить отдельный класс на каждую жалко.

Из коробки пригодятся еще throttle (ограничение частоты запросов, throttle:60,1 значит 60 запросов в минуту), guest (наоборот, пускает только неавторизованных, чтобы залогиненный не видел форму входа) и verified (требует подтвержденный email).

Типичные грабли:

Забытый return перед $next($request). Метод вернет null, Laravel упадет с ошибкой про Response, а вы полчаса будете искать причину не там.

Опечатка в псевдониме или незарегистрированный alias дает ошибку "Target class [admin] does not exist". Проверяйте bootstrap/app.php первым делом.

Редирект-петля: если middleware редиректит на маршрут, который сам закрыт этим же middleware, браузер покажет ERR_TOO_MANY_REDIRECTS. Страница, куда вы уводите пользователя, должна быть открытой.

И не вешайте обычный auth на маршруты из routes/api.php: там нет сессий, для API используют auth:sanctum, до этого доберемся в главе 12.

Что усвоили:

Middleware это конвейер, через который идет каждый запрос. Мы написали свой класс, зарегистрировали псевдоним в bootstrap/app.php и закрыли группу маршрутов для не-админов. В следующей главе займемся очередями: научим приложение выполнять тяжелую работу в фоне, не заставляя пользователя ждать ответа.
👍6 ❤️ 🔥1 😄 🤔
✔ Лучший ответ сформирован автоматически — vault_maker
oleg_php писал(а):Метод вернет null, Laravel упадет с ошибкой про Response наступил ровно на эти грабли позавчера. написал if с abort, а return $next($request) случайно оставил внутри else, и в одной ветке метод ничего не возвращал. ошибка TypeError про Symfony Response вообще не наводила на мысль, что проблема в моем middleware. так что да, проверяйте return первым делом
Перейти к ответу →
Аватара пользователя
vault_maker
Сообщения: 1
Зарегистрирован: 13 май 2026, 00:37

Re: Middleware и защита маршрутов

Сообщение vault_maker »

✔ Лучший ответ — сформирован автоматически
oleg_php писал(а):Метод вернет null, Laravel упадет с ошибкой про Response
наступил ровно на эти грабли позавчера. написал if с abort, а return $next($request) случайно оставил внутри else, и в одной ветке метод ничего не возвращал. ошибка TypeError про Symfony Response вообще не наводила на мысль, что проблема в моем middleware. так что да, проверяйте return первым делом
👍1 ❤️2 🔥 😄 🤔
Аватара пользователя
dragonwolf
Сообщения: 2
Зарегистрирован: 14 май 2026, 01:31

Re: Middleware и защита маршрутов

Сообщение dragonwolf »

А если у пользователя может быть несколько ролей? В уроке пример 'role:editor' с одним аргументом, а можно через запятую передать сразу 'role:admin,editor' и в handle принять их как массив или через ...$roles? Или придется городить два middleware?
👍 ❤️1 🔥 😄 🤔
Аватара пользователя
svelte_enjoyer
Сообщения: 2
Зарегистрирован: 26 май 2026, 03:05

Re: Middleware и защита маршрутов

Сообщение svelte_enjoyer »

У нас на работе легаси на Laravel 10, никакого withMiddleware в bootstrap/app.php там нет. Правильно понимаю, что в этом случае псевдоним прописывается в $middlewareAliases в app/Http/Kernel.php, а сам класс и маршруты выглядят точно так же?
👍3 ❤️1 🔥 😄 🤔
Аватара пользователя
Pberne
Сообщения: 1
Зарегистрирован: 13 май 2026, 07:05

Re: Middleware и защита маршрутов

Сообщение Pberne »

Спасибо за блок про редирект-петлю. Месяц назад ловил ERR_TOO_MANY_REDIRECTS и грешил на nginx на VPS, перезапускал все подряд. Оказалось, повесил кастомную проверку на всю группу включая страницу, на которую сам же редиректил. После этой главы хоть понятно, почему так вышло
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Аутентификация пользователей
Следующая глава →
Очереди и фоновые задачи

Все главы курса «Laravel с нуля»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «Laravel с нуля»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость