web-dev-qa-db-fra.com

Laravel middleware avec plusieurs rôles

J'ai rencontré des problèmes avec le middleware de Laravel. Permettez-moi de vous dire l'idée de base de ce que j'essaie d'accomplir:

Les utilisateurs enregistrés sur le site auront l'un des quatre rôles suivants:

  1. Étudiant (par défaut): peut accéder à ' index ' et ' show ' vues
  2. Approbateur: peut accéder à l'aperçu précédent, plus '', ' update '
  3. Editeur: peut accéder aux précédents, plus ' create ', ' edit ' et ' store '
  4. Admin: peut accéder à tout

fyi: 'aperçu' est en quelque sorte une vue d'index, mais uniquement pour le rôle d'approbateur et supérieur

Selon vous, quelle est la meilleure façon de procéder? C'est ce que j'ai fait jusqu'à présent, mais cela ne semble pas fonctionner:


Kernel.php

protected $middlewareGroups = [
...
    'approver+' => [
        \App\Http\Middleware\Approver::class,
        \App\Http\Middleware\Editor::class,
        \App\Http\Middleware\Admin::class,
    ],
];

protected $routeMiddleware = [
...
    'student' => \App\Http\Middleware\Student::class,
    'approver' => \App\Http\Middleware\Approver::class,
    'editor' => \App\Http\Middleware\Editor::class,
    'admin' => \App\Http\Middleware\Admin::class,
];

Http\Middleware\Admin.php

public function handle($request, Closure $next)
{
   if (Auth::check())
   {

        if(Auth::user()->isAdmin())
        {
            return $next($request);
        }
   }

    return redirect('login');
}

Le modèle éloquent "utilisateur":

public function isAdmin()
{
    if($this->role_id === 4)
    { 
        return true; 
    } 
    else 
    { 
        return false; 
    }
}

J'ai fait exactement la même chose dans les fichiers middleware Approver et Editor, et dans les fonctions isApprover et isEditor du modèle User, j'ai seulement modifié la valeur vérifiée dans l'instruction if à 2 et 3 respectivement.

Enfin, voici ce que j'ai fait dans mon fichier routes\web:

Route::get('scholen', 'SchoolsController@index');
Route::get('admin/scholen/overzicht', 'SchoolsController@overview')->middleware('approver+');
Route::get('admin/scholen/maken', 'SchoolsController@create')->middleware('approver+');
Route::post('scholen', 'SchoolsController@store')->middleware('approver+');
Route::get('scholen/{id}', 'SchoolsController@show');
Route::get('admin/scholen/{id}/bewerken', 'SchoolsController@edit')->middleware('admin');
Route::patch('admin/scholen/{id}', 'SchoolsController@update')->middleware('admin');
Route::delete('admin/scholen/{id}', 'SchoolsController@destroy')->middleware('admin');

Ce n'est pas encore tout à fait exact, mais je suis coincé depuis que lorsque je me connecte en tant qu'utilisateur avec des droits d'approbateur et que j'essaie d'accéder à la vue d'ensemble des écoles, il me redirige vers la page d'accueil.

En général, j'ai l'impression de travailler de manière beaucoup trop chaotique et pas juste du tout, quelqu'un pourrait-il me donner des conseils sur la façon de le faire plus efficacement?

Merci beaucoup d'avance!

10
Jesse

Vous ne devriez pas avoir de middleware séparé pour chaque rôle. Cela deviendra très désordonné très rapidement. Il serait préférable d'avoir un middleware de vérification de rôle unique qui puisse vérifier tout rôle qui lui est transmis.

Http\Kernel.php

protected $routeMiddleware = [
    ...
    'role' => \App\Http\Middleware\Role::class,
];

Http\Middleware\Role.php

public function handle($request, Closure $next, ... $roles)
{
    if (!Auth::check()) // I included this check because you have it, but it really should be part of your 'auth' middleware, most likely added as part of a route group.
        return redirect('login');

    $user = Auth::user();

    if($user->isAdmin())
        return $next($request);

    foreach($roles as $role) {
        // Check if user has the role This check will depend on how your roles are set up
        if($user->hasRole($role))
            return $next($request);
    }

    return redirect('login');
}

Enfin dans vos parcours web

Route::get('admin/scholen/overzicht', 'SchoolsController@overview')->middleware('role:editor,approver');
Route::get('admin/scholen/{id}/bewerken', 'SchoolsController@edit')->middleware('role:admin');
22
jfadich