laravel - Как я могу использовать один и тот же URL-адрес в группе 2 маршрутов

Предположим, у меня есть 2 фильтра

1) Админ 2) Суперадмин

Фильтры:

 Route::filter('Admin', function($route, $request)
 {
   if ( ! Auth::user()->Admin()) {
   return Response::json(array('flash' => 'You are not authorized.'), 401);
 }
});

Route::filter('SuperAdmin', function($route, $request)
{
  if ( ! Auth::user()->SuperAdmin()) {
  return Response::json(array('flash' => 'You are not authorized.'), 401);
}
});

Маршруты:

Route::group(array('before' => array('auth|Admin')), function()
{

    Route::get('/report/{id}','ReportCntrl@getreport');
    Route::get('/create1','ReportCntrl@create1');

}


Route::group(array('before' => array('auth|SuperAdmin')), function()
{

    Route::get('/report/{id}','ReportCntrl@getreport');
    Route::get('/create2','ReportCntrl@create2');
    Route::get('/create3','ReportCntrl@create3');

}

поэтому проблема в том, что когда я вхожу с superadmin, он говорит, что несанкционированный доступ

потому что я думаю, что он передает мой запрос обоим фильтрам, и один одобряет его, а второй не одобряет.

Есть ли способ, который я могу использовать для доступа к одному и тому же URL-адресу из двух групп маршрутов в Laravel.


person AngularDev    schedule 12.12.2014    source источник
comment
почему бы вам не попробовать проверить Admin в самом фильтре SuperAdmin   -  person Saqueib    schedule 12.12.2014
comment
покажите нам код для обоих фильтров, я предлагаю сделать один и сделать что-то вроде if is_admin or is_superadmin return true;   -  person Kyslik    schedule 12.12.2014
comment
попробуйте пользовательские фильтры фильтры Laravel   -  person Arun Kumar    schedule 12.12.2014
comment
потому что у superadmin есть некоторые права, которые не должны быть доступны для администратора.   -  person AngularDev    schedule 12.12.2014
comment
@Kyslik обновил вопрос, пожалуйста, предложите   -  person AngularDev    schedule 12.12.2014
comment
Вы можете создать настраиваемый фильтр, как указано выше, или, в качестве альтернативы, вы можете просто изменить представление в зависимости от разрешений, чтобы оно направляло то же самое, только представление, которое они получают как администратор, будет немного меньше вариантов. вы можете использовать шаблон блейда или, в качестве альтернативы, вы можете просто вернуть 2 разных представления из контроллера 1 для администратора и 1 для суперадминистратора   -  person clonerworks    schedule 12.12.2014
comment
Или вы можете попробовать просто изменить порядок (на самом деле не знаю, работает ли это, но стоит попробовать) поместите маршрут, используя фильтр суперадминистратора выше в коде.   -  person Kyslik    schedule 12.12.2014
comment
@Kyslik также добавил некоторые другие маршруты, пожалуйста, проверьте и предложите   -  person AngularDev    schedule 12.12.2014


Ответы (3)


Вы должны использовать один единственный фильтр. Но вы можете использовать параметры фильтра, чтобы сделать его динамичным и многоразовым.

Route::filter('role', function($route, $request, $value){
    $allowedRoles = explode(';', $value);
    $user = Auth::user();
    if(in_array('Admin', $alloweRoles) && $user->Admin()){
        return;
    }
    else if(in_array('SuperAdmin', $allowedRoles) && $user->SuperAdmin()){
        return;
    }
    return Response::json(array('flash' => 'You are not authorized.'), 401);
});

И вы используете это так:

Route::group(array('before' => array('auth|role:Admin;SuperAdmin')), function(){
    Route::get('/report/{id}','ReportCntrl@getreport');
}

Объяснение

Три параметра фильтра ($route, $request, $value) автоматически передаются в этом порядке Laravel. Третий параметр $value содержит все, что передается после :. документы Laravel

$request — текущий объект запроса (экземпляр Illuminate\Http\Request), а $route — текущий объект маршрута (экземпляр lluminate\Routing\Route)

person lukasgeiter    schedule 12.12.2014
comment
этот потрясающий!! - person Walid Ammar; 12.12.2014
comment
эй, не могли бы вы объяснить мне, что именно я получу в этих трех переменных $route = ?? $ запрос =? $значение=?? - person AngularDev; 12.12.2014
comment
@AngularDev См. раздел laravel.com/docs/4.2/routing "Указание параметров фильтра". - person mauvm; 12.12.2014
comment
если я не ошибаюсь, это не задокументировано должным образом, они не показывают, что я получаю в этих варах - person AngularDev; 12.12.2014
comment
Запросить объект? и объект маршрута? это означает 1) URL-адрес, откуда фильтр получил запрос 2) Имя контроллера, на который он должен попасть. я прав?? - person AngularDev; 12.12.2014
comment
@AngularDev смотрите последнюю строку. хочешь узнать больше? - person lukasgeiter; 12.12.2014
comment
да @lukasgeiter, если возможно, я хочу узнать больше о $request и $route, я имею в виду, что если вы просто подтвердите, правильно или неправильно то, что я прокомментировал выше, мне будет очень полезно понять. - person AngularDev; 12.12.2014
comment
@AngularDev Не совсем так. Они являются экземплярами класса запроса и маршрута. Я снова обновил ответ. - person lukasgeiter; 12.12.2014

Группировка маршрутов Laravel может сбивать с толку из-за порядка определения. Фильтры определяются до маршрутов, но во время маршрутизации сначала сопоставляются маршруты, и только потом применяются фильтры.

То, чего вы пытаетесь достичь, будет работать только в том случае, если ложные фильтры (скажем, SuperAdmin == false) заставят Laravel игнорировать маршрут.

Я бы предложил сделать Auth::user()->Admin() также равным true для суперадминистраторов. Таким образом, равные маршруты будут по-прежнему работать, но все разные маршруты (между группами) будут работать правильно.

person mauvm    schedule 12.12.2014
comment
пример пожалуйста? потому что, если я это сделаю, этот админ сможет получить доступ к маршрутам суперадмина - person AngularDev; 12.12.2014
comment
@AngularDev Правильно ли я предполагаю, что маршруты будут иметь одну и ту же конечную точку? Что /report/{id} перейдет к ReportCntrl@getreport независимо от администратора или суперадминистратора? - person mauvm; 12.12.2014
comment
даа, но если у меня есть маршрут /create2 и /create3 исключительно для суперадмина, что произойдет? - person AngularDev; 12.12.2014
comment
@AngularDev Это все равно будет работать, потому что эти маршруты совпадают и применяется фильтр SuperAdmin. Ваша проблема заключается в дублировании маршрутов и в том факте, что фильтры администратора возвращают ответ 401 вместо проверки соответствия других определенных маршрутов. - person mauvm; 12.12.2014

Вы можете сделать что-то вроде этого:

Route::filter('AdminAndSuperAdmin', function($route, $request)
 {
   if ( ! Auth::user()->Admin() && ! Auth::user()->SuperAdmin()) {
   return Response::json(array('flash' => 'You are not authorized.'), 401);
 }
});



// this route will work for both admin and super admin
Route::group(array('before' => array('auth|AdminAndSuperAdmin')), function()
{

    Route::get('/report/{id}','ReportCntrl@getreport');

} 


Route::group(array('before' => array('auth|Admin')), function()
{

    Route::get('/create1','ReportCntrl@create1');

}


Route::group(array('before' => array('auth|SuperAdmin')), function()
{

    Route::get('/create2','ReportCntrl@create2');
    Route::get('/create3','ReportCntrl@create3');

}
person Walid Ammar    schedule 12.12.2014
comment
см. мой обновленный вопрос, я также добавил некоторые другие маршруты. Пожалуйста, проверьте и предложите - person AngularDev; 12.12.2014
comment
По сути, мне также придется создать одну группу для общего URL-адреса. Вы уверены, что другого пути нет, потому что здесь упомянули только 2 роли, в моем приложении больше ролей, и многие из них используют много общих URL-адресов. - person AngularDev; 12.12.2014
comment
@AngularDev проверьте ответ lukasgeiter ниже, он более динамичен и работает для любого количества правил. - person Walid Ammar; 12.12.2014