banner-tipos-middleware-en-laravel

Los HTTP Middleware como lo explica la documentación de Laravel proporcionan un mecanismo conveniente para filtrar las peticiones HTTP entrantes a una aplicación. En un post anterior conocimos Cómo crear y usar los Middleware en Laravel 5.1, en el cual se explicaba qué son, cómo registrarlos y usarlos. En esta oportunidad estudiaremos los tipos de Middleware que podemos crear en nuestras aplicaciones.

Cada middleware en Laravel se pueden ver como una capa que recibe las peticiones HTTP y analiza si cumplen con algunas condiciones y las pasan a la siguiente capa (quizás otro middleware) hasta llegar al controlador donde se ejecutan las acciones según el tipo de petición (GET, POST, PATCH, DELETE, etc.) para luego enviar una respuesta. Podemos verlo gráficamente de esta manera:

middleware-en-laravel

Es decir que podemos filtrar las peticiones para que se ejecuten las que cumplan con las condiciones de cada Middleware de nuestra aplicación.  

En Laravel un Middleware es una clase que implementa el método handle que acepta como parámetros la petición o $request (Illuminate\Http\Request ) el Closure $next y algunas veces los parámetros definidos por nosotros. Si creamos un nuevo Middleware desde la consola con php artisan make:middleware MyMiddleware  veremos en el directorio /app/Http/Middleware/:

<?php

namespace App\Http\Middleware;

use Closure;

class MyMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

Una forma de clasificar los Middleware es por su manera de ejecutarse en la aplicación: Before Middleware, After Middleware y Terminable Middleware.

Si queremos que el Middleware ejecute tareas antes que la petición sea ejecutada (Before Middleware), entonces colocamos en el método handle:

public function handle($request, Closure $next)
{
    //acciones del middleware

    return $next($request);
}

Ejemplos de este tipo de Middleware puede ser cuando queremos restringir el acceso de usuarios por tipo, por edad, por ubicación, confirmar si el usuario ha iniciado sesión, para trabajar con variables de sesión como vimos en Aplicación multilenguaje en Laravel 5.1. También puede ser usado para verificar los datos de entrada de la petición.

Por otro lado, si queremos el Middleware ejecute tareas después que la petición sea ejecutada pero antes que la respuesta sea enviada (After Middleware), entonces colocamos el código así:

public function handle($request, Closure $next)
{

    $response = $next($request);

       // acciones del middleware

        return $response;
}

Ejemplo de este tipo de middleware puede ser cuando se necesita modificar la respuesta que dará la aplicación ante la petición, manejar las cookies, modificar los headers, entre otros.

Por último están los Terminable Middleware que son aquellos que realizan alguna tarea después que la respuesta haya sido enviada. Éstos implementan un método llamado terminate el cual recibe tanto la petición ($request) como la respuesta ($response). Es decir,

<?php

use Closure;

class MyMiddleware
{
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        // acciones del middleware
    }
}

Ejemplo de este tipo de middleware puede ser para crear cache de las respuestas dadas, guardar o actualizar variables de sesión, crear logs, limpiar datos temporales, etc.

Por tanto, cada tipo de Middleware tiene un área de acción:

tipos-middleware-en-laravel

Adicionalmente, podemos diferenciar a los middleware por su forma de ejecutarse en la aplicación: Globales, por Rutas o  Controladores.

Los Middleware Globales son aquellos que se registran en el array $middleware del archivo app/Http/Kernel.php  que se ejecutarán cada vez que se realice una petición HTTP a la aplicación. Por defecto, Laravel tiene los siguientes:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\VerifyCsrfToken::class,
];

Por su parte los Middleware por Rutas (o controlador) son los que se registran en el array $routeMiddleware del archivo app/Http/Kernel.php  y se ejecutarán únicamente cuando sean llamados por su clave ya sea en una ruta o en un controlador. Por ejemplo los middleware de este tipo que vienen por defecto en Laravel son:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
];

Es decir, que podemos hacer que cada vez que se haga una petición a una ruta que sea evaluada por el middleware ‘auth’, es decir se compruebe si el usuario está autenticado, de esta manera:

Route::get('admin/profile', ['middleware' => 'auth', function () {
    //
}]);

Se puede asignar múltiples middleware usando un array:

Route::get('/', ['middleware' => ['first', 'second'], function () {
    //
}]);

También, en vez de un array, se puede encadenar el método middleware en la definición de la ruta:

Route::get('/', function () {
    //
})->middleware(['first', 'second']);

Por otro lado, igualmente podemos filtrar todos los métodos desde el constructor de un controlador así:

public function __construct()
{
    $this->middleware('auth');
}

o unos aplicarse para ciertos métodos del controlador:

public function __construct()
{
    $this->middleware('auth', ['only' => ['store', 'edit', 'update', 'destroy']]);
}

Las posibilidades y las opciones que nos ofrece trabajar con Middleware son inmensas. Nos provee una manera sencilla pero poderosa para manipular las peticiones y respuestas de nuestras aplicaciones. Espero que esta información les sea útil y no se olviden de compartirla en las redes sociales.

Material relacionado

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.