I make a website on Laravel 5.4.
There are roles: registered, customer-basic, customer-pro, customer-full . For each created a middleware, in which the user is checked whether the user is authorized or not and what his role is:

public function handle($request, Closure $next) { // В других middleware-файлах подставляется своя роль: 'registered', 'customer-full'... if (Sentinel::check() && Sentinel::inRole('customer-pro')) { return $next($request); } else { return redirect()->back()->with(['message' => 'У вас недостаточно прав, чтобы посетить эту страницу 4']); } } 

In the route everything is grouped:

 Route::group(['middleware' => ['registered']], function(){ Route::get('/success-registration', function() { return view('frontend.auth.success'); }); Route::get('/activate/{email}/{activationCode}', [ 'uses' => 'Authentication\ActivationController@activateUser', 'as' => 'activation.user' ]); Route::group(['middleware' => ['customer-basic', 'customer-pro', 'customer-full']], function(){ Route::get('/forgot-password', [ 'uses' => 'Authentication\ForgotPasswordController@index', 'as' => 'forgot.password.view', ]); Route::post('/forgot-password', [ 'uses' => 'Authentication\ForgotPasswordController@sendLink', 'as' => 'forgot.password.send', ]); Route::get('/reset/{email}/{resetCode}', [ 'uses' => 'Authentication\ForgotPasswordController@formReset', 'as' => 'forgot.password.reset.view', ]); Route::post('/reset/{email}/{resetCode}', [ 'uses' => 'Authentication\ForgotPasswordController@reset', 'as' => 'forgot.password.reset', ]); Route::get('/price', [ 'uses' => 'Backend\PriceController@index', 'as' => 'price.table.view', ]); }); }); 

An error is returned to me that I do not have rights to view the page, because I am authorized as 'registered'. But the page / price can look at both 'registered', and 'customer-basic', and 'customer-pro', and 'customer-full'. Here is what needs to be done so that a user with ONE OF the roles can view this page (and not only this one)?

    1 answer 1

    In general, relying on documentation , as well as being inspired and finding some useful things from this question , such a solution was born (I don’t answer for grace, but yes for operability):
    1. in the console, write php artisan make:middleware CheckRoles ;
    2. In the app \ Http \ Middleware \ Kernel.php in the array protected $routeMiddleware add the 'roles' => \App\Http\Middleware\CheckRoles::class,
    3. In routes \ web.php, the routes that should be tested (many roles) are put into a separate “group”, like this:

     Route::group(['middleware' => ['roles:registered|customer-basic|customer-pro|customer-full']], function(){/* Роуты, которые проходят проверку */}); 

    4. In the app \ Http \ Middleware \ CheckRoles.php insert the following construction

     class CheckRoles { public function handle($request, Closure $next, $roles) { if (preg_match('/\|/', $roles)) { $roles = explode('|', $roles); } else { $roles = []; $roles[] = $roles; } foreach ($roles as $role) { try { if (Sentinel::check() && Sentinel::inRole($role)) { return $next($request); } } catch (ModelNotFoundException $exception) { dd('Could not find role ' . $role); } } return redirect()->back()->with(['message' => 'У вас недостаточно прав для просмотра этой страницы']); } } 

    4. In the desired view (or better in the layout (of type master.blade.php)) we display this message:

      @if(session('message')) <div class="alert alert-info alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button> <p>{{ session('message') }}</p> </div> @endif