Skip to content

🧱 Middleware

Middleware — это промежуточный слой, который выполняется до вызова контроллера. Он позволяет централизованно проверять доступ, выполнять авторизацию, защиту от CSRF и многое другое.

🔍 Зачем нужен middleware?

Типичные задачи:

  • 🔐 Авторизация — проверка, вошёл ли пользователь.
  • 🚫 Доступ только для гостей — например, к странице входа.
  • 🛡 CSRF-защита — защита от подделки запросов (только для POST, PUT, PATCH, DELETE).
  • 🔑 Авторизация по токену — для MODX API (modauth).

🛠 Создание middleware

Создай класс в core\App\Http\Middleware, унаследованный от PageBlocks\App\Http\Middleware\Middleware:

php
namespace PageBlocks\App\Http\Middleware;

use Boshnik\PageBlocks\Http\Request;

class ExampleMiddleware extends Middleware
{
    public function handle(Request $request)
    {
        // Логика
        return true;
    }
}

Метод handle(Request $request) должен вернуть:

  • true — чтобы продолжить выполнение маршрута.
  • false — чтобы прервать и вернуть 403.
  • abort($code) — для завершения с конкретным HTTP-кодом.
  • response(...) — если нужно вернуть кастомный ответ, например redirect('/').

📚 Готовые middleware

ПсевдонимНазначение
authТолько для авторизованных пользователей
guestТолько для гостей
csrfCSRF-защита форм
modauthПроверка HTTP_MODAUTH токена (для MODX API)

🔐 Авторизация (auth)

php
class Authenticate extends Middleware
{
    public function handle(Request $request)
    {
        if ($this->modx->user->isAuthenticated($this->modx->context->key)) {
            return true;
        }

        abort(401);
    }
}

🚫 Только для гостей (guest)

php
class Guest extends Middleware
{
    public function handle(Request $request)
    {
        if (!$this->modx->user->isAuthenticated($this->modx->context->key)) {
            return true;
        }

        return redirect('/');
    }
}

🛡 CSRF-защита (csrf)

php
class VerifyCsrfToken extends Middleware
{
    public function handle(Request $request)
    {
        if (
            in_array($request->method(), ['POST', 'PUT', 'PATCH', 'DELETE'], true) &&
            !$this->tokensMatch($request)
        ) {
            return response()->csrfError();
        }

        return true;
    }

    protected function tokensMatch(Request $request): bool
    {
        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
        $session_token = $_SESSION['_csrf_token'];

        return isset($session_token) &&
            is_string($session_token) &&
            is_string($token) &&
            hash_equals($session_token, $token);
    }
}

📌 Важно: этот middleware добавляется автоматически ко всем маршрутам с методами POST, PUT, PATCH, DELETE. Его не нужно указывать вручную.

🧩 Регистрируем псевдонимы

Чтобы использовать короткие имена ('auth', 'csrf'), добавь их в core/App/bootstrap/app.php:

php
return [
    'middleware' => [
        'auth' => Authenticate::class,
        'guest' => Guest::class,
        'csrf' => VerifyCsrfToken::class,
        'modauth' => MODAuthenticate::class,
    ],
];

🔗 Добавление middleware

🧍 К одному маршруту

Можно указать короткий псевдоним:

php
Route::get('/profile', 'UserController@profile')
    ->middleware('auth');

Или полное имя класса:

php
use PageBlocks\App\Http\Middleware\Authenticate;

Route::get('/profile', 'UserController@profile')
    ->middleware(Authenticate::class);

🧺 К группе маршрутов

php
Route::prefix('/account')
    ->middleware(['auth', 'csrf']) // псевдонимы или классы
    ->group(function () {
        Route::get('/', 'AccountController@index');
        Route::post('/update', 'AccountController@update');
    });

🚫 Исключение middleware

Если нужно отключить определённые middleware:

❌ Для одного маршрута

php
Route::post('/webhook', 'WebhookController@handle')
    ->withoutMiddleware('csrf');

❌ Для группы маршрутов

php
Route::middleware(['auth', 'csrf'])
    ->withoutMiddleware('csrf')
    ->group(function () {
        Route::post('/settings', 'SettingsController@update');
    });

💡 Советы

  • Пиши универсально — middleware должен быть независимым от конкретного маршрута.
  • Возвращай response(...), если нужно кастомное поведение (JSON, redirect).
  • CSRF подключается автоматически для всех изменяющих запросов.
  • Комбинируй псевдонимы и классы в middleware() — это гибко и читаемо.

© PageBlocks 2019-present