Разрешение повторяющихся маршрутов на основе группы промежуточного программного обеспечения

В web.php у меня есть две промежуточные группы для двух пользовательских ролей — admins и non_admins:

Route::group(['middleware' => ['auth', 'admin']], function () {
    // if user is logged in AND has a role of admin...
    Route::get('/', 'Admin\IndexController@index');
});

Route::group(['middleware' => ['auth', 'non_admin']], function () {
    // if user is logged in AND has a role of non_admin
    Route::get('/', 'NonAdmin\IndexController@index');
});

И промежуточное ПО admin, и non_admin проверяют, что роль Auth::user() равна admin или non_admin соответственно; если это не так, промежуточное программное обеспечение завершается с ошибкой abort(403). Почему у меня нет единого промежуточного ПО? Смысл этого в том, чтобы разделить две роли, чтобы каждая имела свою собственную независимую логику контроллера и свои представления.

Проблема

Если я вхожу в систему как admin, я получаю 403, если я вхожу как non_admin, все работает как положено. Мое предположение: Laravel видит два повторяющихся маршрута и разрешает только тот, который определен последним (который находится в ['middleware' => ['auth', 'non_admin']]).

Вопрос

Как разрешить повторяющиеся маршруты, но разделить логику контроллера и представления? Опять же, admin и non_admin пользователей посетят один и тот же маршрут ('/'), но увидят два разных представления. Я также хочу реализовать это в двух разных контроллерах.


person Alex    schedule 16.10.2016    source источник
comment
Можете ли вы опубликовать классы промежуточного программного обеспечения? Вероятно, AdminMiddleware работает не так, как ожидалось.   -  person Jan Willem    schedule 17.10.2016
comment
Как вы решили это? У меня точно такая же проблема.   -  person Miguel Stevens    schedule 24.11.2016
comment
@Notflip Очевидно, у вас не может быть дублирующихся маршрутов в Laravel, поскольку они указывают на один и тот же URL-адрес. Вы можете использовать Bouncer для управления ролями.   -  person Alex    schedule 24.11.2016


Ответы (1)


Хм....

Лично я бы все инкапсулировал под общий контроллер, а необходимые проверки и модификации выполнял с помощью сервисного класса.

Но если вы действительно хотите, чтобы все было разделено между двумя разными контроллерами в зависимости от ваших ролей, вы можете сделать это таким образом. Предполагается, что вы используете встроенную авторизацию Laravel:

маршруты

Route::group(['middleware' => ['auth']], function () {
    Route::get('/', function(){
        $isAdmin = Auth::user()->can('do-arbitrary-admin-task');
        $ns = $isAdmin ? 'Admin' : 'NonAdmin';
        $controller = app()->make("{$ns}\\IndexController");
        return $controller->callAction('index', $parameters = []);
    });
});
person maiorano84    schedule 17.10.2016
comment
Спасибо, а под классом обслуживания вы подразумеваете промежуточное ПО? - person Alex; 18.10.2016
comment
Нет, я имею в виду сервисный класс: класс, который абстрагирует бизнес-логику от контроллера. - person maiorano84; 18.10.2016
comment
У вас есть пример такого класса? У меня такая же проблема, спасибо! - person Miguel Stevens; 24.11.2016
comment
Вот пример использования Lumen. По сути, вы можете использовать поставщика услуг, чтобы сообщить контейнеру IoC Laravel, как обрабатывать внедрение зависимостей. Регистрация поставщиков услуг в Laravel и Lumen немного отличается друг от друга, но ненамного. В Laravel вы регистрируете каждого поставщика услуг в файле config/app.php, а в Lumen — в файле bootstrap/app.php. - person maiorano84; 25.11.2016