Laravel routes: filtrare le richieste con i middleware

Utilizzando Laravel con Jetstream per un progetto mi sono trovato nella situazione di dover avere per ogni Team un campo "type" per indicare la tipologia del team creato.

In questo modo in fase di creazione l'utente può indicare la tipologia di team che vuole creare e nel database viene salvato l'ID della tipologia (1,2,3,...) nell'apposita colonna "type".
Ad esempio potrò avere:

  1. utenti base
  2. editor
  3. visualizzatori statistiche
  4. ....

Di conseguenza è possibile recuperare il valore con

Auth::user()->currentTeam->type //restituisce l'id (1,2,3,...)

A questo punto è sorto il secondo problema, ovvero: come faccio a far accedere a determinate sezioni dell'applicazione solo gli utenti di determinate tipologie?
Ad esempio tutti i team possono visualizzare la dashboard, ma solo i team di tipo 2 / EDITOR possono gestire le news.

Possiamo fare questo tramite i Middleware.
Come prima cosa creo il middleware tramite artisan

php artisan make:middleware TeamTypeFilterMiddleware

e nella funzione handle() faccio due cose:

  • accetto un terzo parametro ($type_id)
  • controllo se il type_id del gruppo corrente è uguale al parametro passato e in caso negativo eseguo un redirect (ad esempio alla dashboard)
public function handle(Request $request, Closure $next, $type_id): Response
{
    //controllo il type_id del team corrente
    if(Auth::user()->currentTeam->type != $type_id){
        //eseguo il redirect alla dashboard
        return redirect()->to('/dashboard');
    }

    return $next($request);
}

Ora in app\Http\Kernel.php posso aggiungere un alias della classe all'interno dell'array $middlewareAliases, per poterla richiamare comodamente:

protected $middlewareAliases = [

......altri alias....

'filter_team' => \App\Http\Middleware\FilterTeamMiddleware::class

];

A questo punto è tutto pronto per poter mettere in funzione il middleware.
Nelle routes posso semplicemente raggruppare tutte le sezioni che possono essere visualizzate solo da un determinato gruppo, come nel codice seguente.

Da notare che richiamo il middleware tramite l'alias creato e uso i due punti per passare il parametro, in questo caso il numero "2" che sarà il nostro $type_id.

//sezioni accessibili solo al gruppo 2 / EDITOR
Route::middleware([
    'filter_team:2',//qui posso passare il type_id: 1 utente base, 2 editor, ...
])->group(function () {
    Route::get('/news', News\Index::class)->name('news');
    Route::get('/news/news', News\Create::class)->name('news.create');
    Route::get('/news/edit/{news}', News\Edit::class)->name('news.edit');
});

 


Commenti