首页 > 解决方案 > Laravel 路由:两个不同路由组中的相同路由

问题描述

我目前有两个路线组,其中一个路线组有六条路线,另一个有两条路线(也在前一组中)。

/**
 * Foo Routes for admin
 */
Route::group(['middleware' => 'bar:admin'], function () {
    Route::put('foo/{uuid}/publish', 'FooController@publish');
    Route::put('foo/{uuid}/disable', 'FooController@disable');
    Route::put('foo/{uuid}/enable', 'FooController@enable');
    Route::delete('foo/{uuid}', 'FooController@destroy');
    Route::post('foo', 'FooController@store');
    Route::put('foo/{uuid}', 'FooController@update');
});

/**
 * Foo Routes for creator
 */
Route::group(['middleware' => 'bar:creator'], function () {
    Route::post('foo', 'FooController@store');
    Route::put('foo/{uuid}', 'FooController@update');
});

这种拆分的原因是因为创建者需要访问来自 admin 组的两个路由,但 admin 需要对所有路由的权限。访问是通过中间件提供的bar

但是,每当我admin尝试访问第二个路由组中可用的两条路由之一时,我的bar班级都会拒绝它的请求。它说我必须是creator访问路线的人。这是否意味着路由具有级联行为,其中路由组的最后一个实例是 laravel 使用的一个?如果是这样,我该如何格式化我的路线以避免这个问题?

bar代码:

public function handle($request, \Closure $next, ...$permissionRules)
{
    .
    .
    .

    $userPermissions = $decodedToken['user']['permissions'];

    // If the user does not have every permission defined via route parameters, deny.
    foreach ($permissionRules as $permissions) {
        if (!in_array($permissions, $userPermissions)) {
            return $this->denyResponse();
        }
    }

    // The user has every permission rule defined via route parameters, so allow.
    return $next($request);
}

标签: phplaravelroutes

解决方案


执行此操作的正确方法是自定义您正在使用的中间件 ( bar) 以接受多个权限/角色。

一个简单的方法是传递一个逗号分隔的可接受权限列表,将其转换为数组,然后检查 Auth 用户是否具有传递的权限。

要使用您最初给我们的代码,这是一种实现方式:

首先,为权限组创建一个新的路由组:

/**
 * Foo Routes for admin
 */
Route::group(['middleware' => 'bar:admin'], function () {
    Route::put('foo/{uuid}/publish', 'FooController@publish');
    Route::put('foo/{uuid}/disable', 'FooController@disable');
    Route::put('foo/{uuid}/enable', 'FooController@enable');
    Route::delete('foo/{uuid}', 'FooController@destroy');
});

/**
 * Foo Routes for creator
 */
Route::group(['middleware' => 'bar:creator'], function () {
    // Other Routes available only to Creator permission users
});

/**
 * Foo Routes for creator & admin
 */
Route::group(['middleware' => 'bar:creator,admin'], function () {
    Route::post('foo', 'FooController@store');
    Route::put('foo/{uuid}', 'FooController@update');
});

二、更新bar中间件,将逗号分隔的字符串转换为数组

public function handle($request, \Closure $next, ...$permissionRules)
{
    .
    .
    .

    $permissionRules = explode(',', $permissionRules);

    $userPermissions = $decodedToken['user']['permissions']; //Assuming this is an array of the Auth'ed user permissions. 

    // If the user does not have every permission defined via route 
parameters, deny.
    foreach ($permissionRules as $permission) {
        if (in_array($permission, $userPermissions)) {
            // Change this to see if the permission is in the array, opposed to NOT in the array
            return $next($request);
        }
    }

    // Made it so that if the permission is NOT found in the array then Deny
    return $this->denyResponse();
}

这应该是你所需要的。希望这可以帮助!


推荐阅读