Guida Laravel: Middleware, cosa sono e come utilizzarli?

Stato
Discussione chiusa ad ulteriori risposte.

SyncroIT

Utente Emerald
13 Gennaio 2014
674
94
208
523
Cosa è un middleware?
Per capire meglio cos'è un middleware, dobbiamo prima capire come funziona Laravel e come vengono gestite le richieste alla nostra applicazione.

diagram.png

L'immagine sovrastante ci fa capire, con molta sintesi, il lifecycle di una richiesta.
Il kernel, che viene subito dopo l'invio della richiesta, gestisce l'URL e i parametri di quest'ultima, per poi passarli al controller, che effettua operazioni sui dati di essa, confrontandosi anche coi modelli, per poi generare una risposta.

Il middleware
Il middleware, nell'immagine di cui sopra, si piazza esattamente tra il Controller e il Kernel.
Ci permette di effettuare dei controlli "aggiuntivi" sulla richiesta o sul gruppo di richieste, limitando l'accesso ad alcune risorse per fornirlo ad altre.

Come utilizzarlo?
Ipotizziamo di avere un'applicazione Laravel suddivisa in 3 parti:
  • Una parte pubblica
    Questa sarà accessibile a chiunque: utenti, crawler, spider, etc.

  • Una parte privata
    Questa sarà accessibile solo agli utenti registrati

  • Un pannello di amministrazione
    Questo pannello, invece, sarà visibile solo agli admin
Il nostro file delle route (routes/web.php) sarà quindi composto in tale modo:


PHP:
// Sito accessibile a tutti
Route::group(['prefix' => '/'], function() {
    Route::get('/', 'Public@getHomepage');
});

// Parte riservata agli utenti
Route::group(['prefix' => 'user'], function() {
    Route::get('/', 'User@getHomepage');
});

// Pannello di amministrazione
Route::group(['prefix' => 'admin'], function() {
    Route::get('/', 'Admin@getHomepage');
});

Apriamo quindi il terminale / prompt dei comandi nella cartella del nostro progetto, e scriviamo:

Codice:
php artisan make:middleware AllowOnlyUsers

Questo comando creerà un middleware che sarà possibile trovare in App/Http/Middleware.
La struttura base di tale file è composta in tale modo:
PHP:
<?php

namespace App\Http\Middleware;

use Closure;

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

Attraverso il metodo handle è possibile gestire la richiesta che sta arrivando al middleware. In questo caso dovremo semplicemente evitare che i visitatori entrino alla parte riservata agli utenti della nostra applicazione.

Per fare ciò, andiamo ad aggiungere del codice nel metodo handle:
PHP:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class AllowUsersOnly
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        /**
         * Verifico se l'utente è un visitatore.
         * Quando l'utente non è registrato / è un visitatore, Auth::check() ritorna false.
         */
        if(!Auth::check()) return redirect()->action('Public@getHomepage')->with('error', 'Access Denied!');
        return $next($request);
    }
}

Il codice che abbiamo aggiunto è molto semplice: controlla se l'utente non è loggato e se non lo è effettua il redirect all'homepage pubblica, flashando dei dati, di cui 'error' è la chiave e 'Access Denied' il contenuto.
I dati "flashati" possono essere reperiti accedendo ai dati di sessione attraverso il facade Session o l'helper session().

Esempio:
PHP:
Session::get('error');
session('error');

I middleware non funzionano per magia, infatti vanno assegnati a uno o più routes, per farlo rechiamoci nel file Kernel per registrare il middleware e assegnarli un nome. Il file Kernel si trova in app/Http/Kernel.php
Alla fine del file, troviamo questa variabile contenente un Array, modifichiamola aggiungendo un nuovo campo come nel codice seguente:

PHP:
/**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'allowUsersOnly' => \App\Http\Middleware\AllowUsersOnly::class
    ];

Il middleware che abbiamo registrato è 'allowUsersOnly', e potremo riutilizzarlo nel file delle route con tale nome.

Vediamo quindi come assegnarlo alle varie route. Rechiamoci innanzitutto nel file delle route (web.php) e modifichiamolo come segue:
PHP:
// Parte riservata agli utenti
Route::group(['prefix' => 'user', 'middleware' => 'allowUsersOnly'], function() {
    Route::get('/', 'User@getHomepage');
});

Adesso, tutte le route sotto il gruppo "user" saranno protette dal middleware che abbiamo creato, e di conseguenza saranno inaccessibili agli utenti non registrati, che verranno riportati all'homepage degli utenti non registrati.
 
  • Mi piace
Reazioni: Valley e Kolo93
Stato
Discussione chiusa ad ulteriori risposte.