Middleware
Middleware — это посредник между запросом и контроллером. Каждый запрос проходит через цепочку посредников, и любой из них может проверить запрос, изменить его или остановить. Так делают проверку входа, ограничение частоты запросов, запись в журнал.
Создание
php artisan make:middleware EnsureIsAdminКласс появится в app/Http/Middleware.
Метод handle
Посредник получает запрос и функцию $next, которая передаёт запрос дальше по цепочке:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureIsAdmin
{
public function handle(Request $request, Closure $next)
{
if (! $request->user()?->is_admin) {
abort(403);
}
return $next($request);
}
}Если условие не выполнено, запрос до контроллера не дойдёт — пользователь увидит ошибку 403.
Подключение к маршруту
use App\Http\Middleware\EnsureIsAdmin;
Route::get('/admin', [AdminController::class, 'index'])
->middleware(EnsureIsAdmin::class);Группа маршрутов
Чтобы не повторять посредника у каждого маршрута, их объединяют в группу:
Route::middleware(EnsureIsAdmin::class)->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
Route::get('/admin/users', [AdminController::class, 'users']);
});Встроенные посредники
У готовых посредников Laravel есть короткие имена:
| Имя | Что делает |
|---|---|
auth | Пускает только вошедших пользователей |
guest | Пускает только тех, кто не вошёл |
throttle:60,1 | Не больше 60 запросов в минуту |
verified | Требует подтверждённый адрес почты |
Route::get('/profile', [ProfileController::class, 'show'])->middleware('auth');Код после ответа
Посредник может выполнить действие и после контроллера — для этого ответ сначала получают из $next:
public function handle(Request $request, Closure $next)
{
$response = $next($request);
$response->headers->set('X-App-Version', '1.0');
return $response;
}Частая ошибка
Если забыть return $next($request);, цепочка оборвётся: контроллер не будет вызван, а пользователь получит пустую страницу. Каждая ветка метода handle() должна либо вернуть результат $next, либо явно остановить запрос — через abort() или redirect().