Skip to content

Middleware

Middleware provides a convenient mechanism for filtering HTTP requests entering your application. Middleware in Sroute follows a Last-In-First-Out (LIFO) execution order.

All middleware classes must implement the handle() method that accepts a callable $next parameter:

<?php
namespace Middleware;
class AuthMiddleware
{
/**
* Handle the incoming request.
*
* @param callable $next The next callable in the pipeline
* @return void
*/
public function handle(callable $next)
{
// Check if user is authenticated
if (!isset($_SESSION['user_id'])) {
header('Location: /login');
exit;
}
// Continue to next middleware or controller
$next();
}
}

Register middleware aliases in your bootstrap file to use short names in routes:

<?php
use Krag\Sroute\Router;
use Middleware\AuthMiddleware;
use Middleware\GuestMiddleware;
use Middleware\CsrfMiddleware;
$router = new Router();
// Register middleware aliases
$router->aliasMiddleware('auth', AuthMiddleware::class);
$router->aliasMiddleware('guest', GuestMiddleware::class);
$router->aliasMiddleware('csrf', CsrfMiddleware::class);

Attach middleware to routes using the middleware() method:

// Single middleware
$router->get('/dashboard', DashboardController::class, 'index')
->middleware(['auth']);
// Multiple middleware
$router->post('/login', AuthController::class, 'login')
->middleware(['csrf', 'guest']);

Middleware executes in LIFO (Last-In-First-Out) order. This means the last middleware added runs first.

$router->post('/checkout', CheckoutController::class, 'process')
->middleware(['csrf', 'auth']);

Execution flow:

  1. CsrfMiddleware runs first (last in array)
  2. AuthMiddleware runs second
  3. Controller action runs last

This allows you to wrap inner middleware with outer ones. For example, CSRF protection should verify the token before authentication checks run.

Redirect authenticated users away from login/register pages:

<?php
namespace Middleware;
class GuestMiddleware
{
public function handle(callable $next)
{
if (isset($_SESSION['user_id'])) {
header('Location: /dashboard');
exit;
}
$next();
}
}

Protect against Cross-Site Request Forgery:

<?php
namespace Middleware;
class CsrfMiddleware
{
public function handle(callable $next)
{
$token = $_POST['csrf_token'] ?? '';
$sessionToken = $_SESSION['csrf_token'] ?? '';
if (!hash_equals($sessionToken, $token)) {
http_response_code(403);
echo 'CSRF token mismatch';
exit;
}
$next();
}
}

Check user permissions:

<?php
namespace Middleware;
class AdminMiddleware
{
public function handle(callable $next)
{
$userRole = $_SESSION['user_role'] ?? null;
if ($userRole !== 'admin') {
http_response_code(403);
echo 'Access denied';
exit;
}
$next();
}
}
  1. Keep middleware focused: Each middleware should have a single responsibility
  2. Always call $next(): Unless you want to terminate the request
  3. Use early returns: Exit early for failed checks to avoid unnecessary processing
  4. Register aliases: Use short, descriptive names for middleware