Middleware & Authentication

Middleware filters HTTP requests before they reach your controller. Rhapsody includes auth and guest middleware out of the box, and you can create your own.

How Middleware Works

Middleware classes must implement a handle(Request $request): ?Response method. If the middleware returns a Response object (e.g., a redirect or error response), the request is short‑circuited and that response is sent immediately. If it returns null, the request proceeds to the next middleware or controller.

Configuration (No Core Edits)

Middleware configuration is stored in config/middleware.php – never modify files inside /core. This keeps your customisations safe during framework updates.

The middleware.php File

// config/middleware.php
return [
    // Route‑specific middleware (key => class)
    'map' => [
        'auth'    => \App\Middleware\AuthMiddleware::class,
        'guest'   => \App\Middleware\GuestMiddleware::class,
        // Add your own:
        // 'admin' => \App\Middleware\AdminMiddleware::class,
    ],
    // Global middleware (runs on every matched request)
    'global' => [
        \App\Middleware\VerifyCsrfTokenMiddleware::class,
    ],
];

Assigning Middleware to Routes

Chain the middleware() method to your route definition using the keys defined in middleware.php.

// Only for authenticated users
Router::get('/dashboard', [PageController::class, 'dashboard'])->middleware('auth');

// Only for guests
Router::get('/login', [AuthController::class, 'showLoginForm'])->middleware('guest');

Creating Custom Middleware

  1. Create a class in app/Middleware extending App\Middleware\Middleware.
  2. Implement the handle(Request $request): ?Response method.
  3. Add an entry to the 'map' array in config/middleware.php.
// Example AdminMiddleware
namespace App\Middleware;

use Rhapsody\Core\Request;
use Rhapsody\Core\Response;
use Rhapsody\Core\Session;

class AdminMiddleware extends Middleware
{
    public function handle(Request $request): ?Response
    {
        if (Session::get('user_role') !== 'admin') {
            return redirect('/');
        }
        return null;
    }
}

Then register it in config/middleware.php:

'map' => [
    // ...
    'admin' => \App\Middleware\AdminMiddleware::class,
],

Included Middleware

  • auth – redirects to /login if no user is logged in.
  • guest – redirects to /dashboard if a user is already logged in.
  • VerifyCsrfTokenMiddleware – global middleware that validates CSRF tokens on unsafe methods.