Laravel 10 Middleware in 5 minutes

Middleware in Laravel is a powerful feature that allows you to filter incoming HTTP requests before they reach your application's routes. Middleware can be used to perform a wide range of tasks, such as authentication, authorization, input validation, and logging. Essentially, middleware acts as a middleman between your application's routes and the incoming request, allowing you to modify or filter the request before it is handled by your application's logic.

Middleware functions are defined as classes that implement the Illuminate\Contracts\Http\Kernel interface, and they typically contain a single handle() method that performs the middleware's specific task. Middleware classes are added to your application's HTTP kernel, which is responsible for managing the middleware pipeline that each incoming request is processed through.

The middleware pipeline is defined using the middleware() method in your application's route files (e.g. web.php, api.php). Middleware can be applied to individual routes or groups of routes, and you can specify the order in which middleware is executed using the middlewarePriority property in your HTTP kernel.

For example, let's say you want to authenticate users before they can access certain routes in your application. You could define a middleware class that checks whether the user is authenticated, and then add that middleware to the routes that require authentication using the middleware() method. Here's an example:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class Authenticate
{
    public function handle(Request $request, Closure $next)
    {
        if (! $request->session()->has('user_id')) {
            return redirect()->route('login');
        }

        return $next($request);
    }
}

In this example, we've defined a middleware class called Authenticate that checks whether the user is authenticated. If the user is not authenticated, the middleware redirects the user to the login page. If the user is authenticated, the middleware passes the request along to the next middleware or the final route handler.

To apply this middleware to a route, we can use the middleware() method in our route definition, like this:

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

In this example, we've added the auth middleware to our /dashboard route, which means that the Authenticate middleware will be executed before the final route handler.

Overall, middleware is a powerful feature in Laravel that allows you to filter incoming HTTP requests and modify them before they are handled by your application's logic. By using middleware, you can add additional layers of security, improve performance, and ensure that incoming requests are properly formatted and validated.

How to define a Middleware?

Running the php artisan make:middleware command is the first step in creating a middleware class in Laravel.

Now that you've generated the EnsureTokenIsValid middleware class, you can open the file at app/Http/Middleware/EnsureTokenIsValid.php and add your middleware logic.

The handle() method of your middleware class should receive the incoming HTTP request and a closure representing the next middleware or the final route handler in the pipeline. The method should perform some specific task, such as checking the validity of an authentication token, before either passing the request to the next middleware in the pipeline or returning a response to the client.

Here's an example implementation of the handle() method for the EnsureTokenIsValid middleware:

public function handle($request, Closure $next)
{
    $token = $request->header('Authorization');

    if (!$token || $token !== 'valid_token') {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    return $next($request);
}

In this example, the middleware checks if the incoming request has a valid Authorization header with a value of valid_token. If the header is missing or has an invalid value, the middleware returns a 401 Unauthorized response to the client. Otherwise, it passes the request to the next middleware in the pipeline.

Once you've implemented your middleware logic, you can register the middleware in your Laravel application's app/Http/Kernel.php file. To register the EnsureTokenIsValid middleware, add it to the $middleware property:

protected $middleware = [
    // ...
    \App\Http\Middleware\EnsureTokenIsValid::class,
];

You can also apply the middleware to specific routes by using the middleware() method in your route definition, like this:

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

This will apply the EnsureTokenIsValid middleware to the /protected route, ensuring that only requests with a valid authentication token can access the route.

How to register Middleware?

n Laravel, you can register middleware at three different levels: globally, for a specific group of routes, or for an individual route.

To register middleware globally, you can add it to the $middleware array in the App\Http\Kernel class. The $middleware array contains a list of all middleware classes that should be run for every incoming request. To add a new middleware class to this array, simply add it to the end of the list:

protected $middleware = [
    \App\Http\Middleware\FirstMiddleware::class,
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    // ...
    \App\Http\Middleware\LastMiddleware::class,
];

This will run the FirstMiddleware middleware before any other middleware or route handler, and it will run the LastMiddleware middleware after all other middleware and the route handler.

To register middleware for a specific group of routes, you can create a new middleware group in the App\Http\Kernel class. A middleware group is a named array of middleware that can be applied to a set of routes using the middleware() method:

protected $middlewareGroups = [
    'api' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\EnsureTokenIsValid::class,
    ],
];

In this example, the api middleware group contains three middleware classes: EncryptCookies, SubstituteBindings, and EnsureTokenIsValid. You can apply this middleware group to a set of routes using the middleware() method:

Route::middleware('api')->group(function () {
    Route::get('/users', 'UserController@index');
    Route::post('/users', 'UserController@store');
});

This will apply the api middleware group to the /users GET and POST routes in the example.

Finally, you can register middleware for an individual route by using the middleware() method on the route definition:

Route::get('/dashboard', 'DashboardController@index')
    ->middleware('auth');

This will apply the auth middleware to the /dashboard route in the example.

In Laravel, you can exclude specific middleware from being applied to a route or group of routes. This can be useful when you have a global middleware that should be applied to most routes, but you want to exclude it from a few specific routes.

To exclude middleware from a single route, you can use the withoutMiddleware() method

Route::get('/public', 'PublicController@index')
    ->withoutMiddleware(\App\Http\Middleware\CheckToken::class);

In this example, the CheckToken middleware will be excluded from the /public route.

To exclude middleware from a group of routes, you can use the middleware() method with an array of middleware classes to exclude:

Route::middleware(['web', 'auth'])
    ->group(function () {
        Route::get('/dashboard', 'DashboardController@index');
        Route::get('/settings', 'SettingsController@index')
            ->withoutMiddleware(\App\Http\Middleware\CheckToken::class);
    });

n this example, the CheckToken middleware will be excluded from the /settings route, but it will still be applied to the /dashboard route because it is not excluded.

Note that you can also exclude middleware globally by removing it from the $middleware array in the App\Http\Kernel class. However, this should be done with caution, as it can have unintended consequences if you forget which middleware you have excluded.

Thats all for now. In the next tutorial we'll learn about sorting middleware