Middleware
Introduction
Middleware provide a convenient mechanism for inspecting and filtering HTTP requests entering your application. For example, Lacelium includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to your application's login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
Additional middleware can be written to perform a variety of tasks besides authentication. For example, a logging middleware might log all incoming requests to your application, or a CORS middleware might add cross-origin headers to outgoing responses.
Defining Middleware
To create a new middleware, you can use the Dipper console command:
php console make:middleware EnsureUserIsSubscribed
This command will place a new EnsureUserIsSubscribed class within your app/Http/Middleware directory. In this middleware, we will only allow access to the route if the user has an active subscription; otherwise, we will redirect the users back to the billing portal:
<?php
declare(strict_types=1);
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
class EnsureUserIsSubscribed
{
/**
* Handle an incoming request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param callable $next
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handle(Request $request, callable $next): Response
{
$user = $request->getSession()->get('user');
if (!$user || !$user['is_subscribed']) {
return new RedirectResponse('/billing');
}
return $next($request);
}
}
Before & After Middleware
Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task before the request is handled by the application:
public function handle(Request $request, callable $next): Response
{
// Perform action before request...
return $next($request);
}
However, this middleware would perform its task after the request is handled by the application:
public function handle(Request $request, callable $next): Response
{
$response = $next($request);
// Perform action after response is generated...
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
return $response;
}
Registering Middleware
Global Middleware
If you want a middleware to run during every HTTP request to your application, list the middleware class in the global middleware array in config/middleware.php:
// config/middleware.php
return [
'global' => [
\App\Http\Middleware\StartSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\TrimStrings::class,
],
];
Assigning Middleware to Routes
If you would like to assign middleware to specific routes, you can define an alias in config/middleware.php and attach it to your route definition in config/routes.php:
// In config/routes.php
$routes->get('/profile', 'show', 'profile')->middleware('auth');
// Or assign middleware to an entire group of routes:
$routes->group('/admin', function ($routes) {
$routes->get('/dashboard', 'dashboard', 'admin.dashboard');
$routes->get('/settings', 'settings', 'admin.settings');
})->middleware(['auth', 'admin']);
Common Middleware Patterns
- Authentication Guards: Ensure incoming users have an active authenticated session.
- Role & Permission Checks: Verify user capability flags before permitting administrator operations.
- Rate Limiting: Throttle IP addresses exceeding allowed request frequencies.
- Locale Switching: Inspect browser language headers and configure
app_set_locale().
Next Steps
- Learn about data persistence in Database Manager.
- Explore model design in Models Architecture.
- Discover utility functions in Helpers Reference.