sajad torkamani

In a nutshell

Middleware lets you inspect or filter incoming HTTP requests. For example, Laravel 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. A variety of middleware are included in Laravel, including middleware for authentication and CSRF protection; however, all user-defined middleware are typically located in your application’s app/Http/Middleware directory.

It’s best to envision middleware as a series of “layers” HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.

Define a middleware

php artisan make:middleware EnsureTokenIsValid

Example middleware

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class EnsureTokenIsValid
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->input('token') !== 'my-secret-token') {
            return redirect('/home');
        }
 
        return $next($request);
    }
}

Before vs After middleware

Before:

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class BeforeMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        // Perform action
 
        return $next($request);
    }
}

After:

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class AfterMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);
 
        // Perform action
 
        return $response;
    }
}

Global middleware

If you want a middleware to run during every HTTP request to your application, you may append it to the global middleware stack in your application’s bootstrap/app.php file:

use App\Http\Middleware\EnsureTokenIsValid;
 
->withMiddleware(function (Middleware $middleware) {
     $middleware->append(EnsureTokenIsValid::class);
})

Route-specific middleware

Single middleware:

use App\Http\Middleware\EnsureTokenIsValid;
 
Route::get('/profile', function () {
    // ...
})->middleware(EnsureTokenIsValid::class);

Multiple middleware:

use App\Http\Middleware\EnsureTokenIsValid;
 
Route::get('/profile', function () {
    // ...
})->middleware(EnsureTokenIsValid::class);

### Exclude single middleware:

use App\Http\Middleware\EnsureTokenIsValid;
 
Route::middleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/', function () {
        // ...
    });
 
    Route::get('/profile', function () {
        // ...
    })->withoutMiddleware([EnsureTokenIsValid::class]);
});

Exclude multiple middleware:

use App\Http\Middleware\EnsureTokenIsValid;
 
Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/profile', function () {
        // ...
    });
});

Middleware groups

Sometimes you may want to group several middleware under a single key to make them easier to assign to routes. You may accomplish this using the appendToGroup method within your application’s bootstrap/app.php file:

use App\Http\Middleware\First;
use App\Http\Middleware\Second;
 
->withMiddleware(function (Middleware $middleware) {
    $middleware->appendToGroup('group-name', [
        First::class,
        Second::class,
    ]);
 
    $middleware->prependToGroup('group-name', [
        First::class,
        Second::class,
    ]);
})

Middleware groups may be assigned to routes and controller actions using the same syntax as individual middleware:

Route::get('/', function () {
    // ...
})->middleware('group-name');
 
Route::middleware(['group-name'])->group(function () {
    // ...
});

Laravel’s Default Middleware Groups

See here.

Middleware aliases

You may assign aliases to middleware in your application’s bootstrap/app.php file. Middleware aliases allow you to define a short alias for a given middleware class, which can be especially useful for middleware with long class names:

use App\Http\Middleware\EnsureUserIsSubscribed;
 
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'subscribed' => EnsureUserIsSubscribed::class
    ]);
})

Once the middleware alias has been defined in your application’s bootstrap/app.php file, you may use the alias when assigning the middleware to routes:

Route::get('/profile', function () {
    // ...
})->middleware('subscribed');

Middleware parameters

See here.

Middleware that runs after HTTP response

See here.

Sources & further reading

Tagged: Laravel