Skip to content

🧱 Middleware

Middleware is an intermediate layer that executes before the controller is called. It allows centralized access checks, authorization, CSRF protection, and much more.

🔍 Why use middleware?

Common tasks:

  • 🔐 Authorization — checking if the user is logged in.
  • 🚫 Guests only — e.g., for a login page.
  • 🛡 CSRF protection — protection against request forgery (only for POST, PUT, PATCH, DELETE).
  • 🔑 Token authorization — for MODX API (modauth).

🛠 Creating middleware

Create a class in core\App\Http\Middleware, extending 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)  
    {  
        // Logic  
        return true;  
    }  
}

The handle(Request $request) method should return:

  • true — to continue executing the route.
  • false — to abort and return a 403 error.
  • abort($code) — to terminate with a specific HTTP code.
  • response(...) — to return a custom response, e.g., redirect('/').

📚 Built-in middleware

AliasPurpose
authOnly for authenticated users
guestOnly for guests
csrfCSRF protection for forms
modauthChecks HTTP_MODAUTH token (for MODX API)

🔐 Authorization (auth)

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

        abort(401);  
    }  
}

🚫 Guests only (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 protection (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);  
    }  
}

📌 Important: This middleware is automatically added to all routes with POST, PUT, PATCH, DELETE methods. You don’t need to specify it manually.

🧩 Registering aliases

To use short names ('auth', 'csrf'), add them to core/App/bootstrap/app.php:

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

🔗 Adding middleware

🧍 To a single route

You can use a short alias:

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

Or the full class name:

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

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

🧺 To a route group

php
Route::prefix('/account')  
    ->middleware(['auth', 'csrf']) // aliases or classes  
    ->group(function () {  
        Route::get('/', 'AccountController@index');  
        Route::post('/update', 'AccountController@update');  
    });

🚫 Excluding middleware

If you need to disable specific middleware:

❌ For a single route

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

❌ For a route group

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

💡 Tips

  • Keep it universal — middleware should be independent of specific routes.
  • Use response(...) if you need custom behavior (JSON, redirect).
  • CSRF is enabled automatically for all modifying requests.
  • Combine aliases and classes in middleware() — it's flexible and readable.

© PageBlocks 2019-present