Разграничение прав доступа Laravel 5.4

440
10 мая 2017, 10:05

Делаю сайт на Laravel 5.4.
Есть роли: registered, customer-basic, customer-pro, customer-full. Для каждого создал middleware, в котором проверяется пользователь авторизован или нет и какая у него роль:

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']);
    }
}

В роуте всё сгруппировано:

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',
    ]);
    });
});

Мне возвращается ошибка, что у меня нет прав, чтобы посмотреть страницу, потому что я авторизован как 'registered'. Но страницу /price смотреть может и 'registered', и 'customer-basic', и 'customer-pro', и 'customer-full'. Вот что надо сделать, чтобы юзер с ОДНОЙ ИЗ ролей мог посмотреть эту страницу (ну и не только эту) ?

Answer 1

В общем, опираясь на документацию, а также вдохновишись и найдя некоторые полезные вещи из этого вопроса, родилось такое решение (за изящество не отвечаю, а за работоспособность - да):
1. в консоли пишем php artisan make:middleware CheckRoles;
2. В app\Http\Middleware\Kernel.php в массив protected $routeMiddleware добавляем 'roles' => \App\Http\Middleware\CheckRoles::class,
3. В routes\web.php роуты, которые должны проходить проверку (множество ролей), выносим в отдельную "группу", типа так:

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

4. В app\Http\Middleware\CheckRoles.php вставляем следующую конструкцию

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. В нужном view (или лучше в лэйауте (типа master.blade.php)) выводим это сообщение:

    @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
READ ALSO
Invalid pointer addition

Invalid pointer addition

Не понимаю, в одном проекте такой кусок кода работал с БД MSSQL, а здесь выдает ошибку, что в том проекте, я объявил глобальную переменную, что...

279
Библиотека не зарегистрирована. visual studio 2015

Библиотека не зарегистрирована. visual studio 2015

Подскажите, пожалуйста, кто сталкивался, что делать? О какой библиотеке идет речь?

329
Шаблоны std::function со сложными типами

Шаблоны std::function со сложными типами

Всем приветИмеется программа моделирующая поведение системы n-тел во времени

356
Функция MPI_Bcast не передает массив

Функция MPI_Bcast не передает массив

Изучаю параллельное программирование (MPI)При попытке передать массив всем процессам с помощью функции MPI_Bcast, сталкиваюсь с тем, что его получает...

272