Выполнять код на каждой или указанной страницы (middleware)

Middleware — технология, которая «перехватывает» запросы на каждой странице, позволяя создать проверки (например, что пользователь авторизован или передан токен).

Сначала надо создать middleware:

php artisan make:middleware VerifyToken

В результате будет создан файл app/Http/Middleware/VerifyToken.php.

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyToken
{
    public function handle(Request $request, Closure $next): Response
    {
        // код, который будет выполняться на каждой странице
        return $next($request);
    }
}

Чтобы код (middleware) выполнялся на каждой странице, надо добавить только что созданный middleware в bootstrap/app.php.

->withMiddleware(function (Middleware $middleware): void {
    // ...
    $middleware->append(\App\Http\Middleware\VerifyToken::class);
});

До версии Laravel 11, данный код указывался в файле app/Http/Kernel.php.

Выполнять код (middleware) только в web.php или api.php

Выполнять middleware только в web.php или api.php можно через код ниже:

->withMiddleware(function (Middleware $middleware): void {
    // Выполнять middleware только в web.php
    $middleware->web(append: [
        \App\Http\Middleware\VerifyToken::class
    ]);

    // Выполнять middleware только в api.php
    $middleware->api(append: [
        \App\Http\Middleware\VerifyToken::class
    ]);
})

Также в middleware можно отловить текущую страницу, если она задана в name().

public function handle(Request $request, Closure $next): Response
{
    if ($request->route()->named('login')) {
        // код, если имя текущей ссылки задана как "login"
    }
 
    return $next($request);
}

Выполнять код (middleware) на указанных страницах

Сначала для middleware надо задать имена (alias).

->withMiddleware(function (Middleware $middleware): void {
    $middleware->alias([
        'verify-token' => App\Http\Middleware\VerifyToken::class
    ]);
})

Теперь можно выполнять middleware на указанных страницах.

Route::get('personal/', [UserController::class, 'personal'])->middleware('verify-token');

Также middleware можно сгруппировать:

// 1-ый способ
Route::middleware(['verify-token'])->group(function () {
    Route::get('personal/', [UserController::class, 'personal']);
    Route::get('notifications/', [UserController::class, 'notifications']);
})

// 2-ой способ
Route::group(['middleware' => 'verify-token'], function(){
    Route::get('personal/', [UserController::class, 'personal']);
    Route::get('notifications/', [UserController::class, 'notifications']);
})

Выполнять middleware в контроллере

Можно указать в контроллере, какой middleware выполнять:

В версиях Laravel 11 и выше:

use Illuminate\Routing\Controllers\{HasMiddleware, Middleware};

class UserController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            'verify-token', // на всех страницах
            new Middleware('verify-token', only: ['index']), // только в экшене "index"
            new Middleware('verify-token', except: ['index']), // во всех экшенах, кроме "index"
        ];
    }
}

В версиях Laravel 10 и ниже: 

class UserController extends Controller
{
    public function __construct()
    {
        // Выполнять middleware во всех экшенов
        $this->middleware('auth');

        // Выполнять middleware только в экшене index
        $this->middleware('log')->only('index');

        // Выполнять middleware во всех экшенах, кроме store
        $this->middleware('subscribed')->except('store');
    }
}