繁体   English   中英

Laravel 5.1 ACL路由资源不起作用

[英]Laravel 5.1 ACL route resource not working

在关于laravel的内置acl如何工作的教程之后我尝试了它并且通过自己定义每个路径它很好。

现在我正在尝试使用资源,但它没有按预期工作。 我将以下代码添加到我的路由文件中:

Route::group(['middleware' => 'acl:create_client'], function()
{
    Route::resource('clients', 'ClientController');
});

现在我明白了问题所在:

如果此用户具有acl:create_client,则将针对我的db检查Clientcontroller中的所有方法,从而导致具有此acl的登录用户可以使用所有方法。

如何拆分每个方法以使用它自己的acl而不必像这样写:

Route::get('/client/create', [
    'middleware' => 'acl:create_client',
    'as' => 'clients.create',
    'uses' => 'ClientController@create'
]);

结果是这样的:

create needs create_client

index需要index_client

更新需要update_client

等等

底线是:您需要以某种方式在访问控制列表(ACL)中设置“列表”。 IMO,最灵活的方法是根据会话用户从数据库中提取此列表; 你有一个良好的开端。 您可以使用在路径中定义的已指定'as'跳过显式路径分配。 示例路线:

Route::get('/', ['as'=>'clients.create', 'uses'=>'ClientsController@create']);

在这里,您将在ACL检查中使用'clients.create' 请记住:ACL仍然需要为所有路由设置'as'值(无论如何都要做好)。

一步步

现在您已获得所需的背景信息,以下是如何使其工作。 这些步骤假设您能够正确设置教程代码和数据库。 这将坚持原始的教程设置,并将专注于使ACL独立于路由配置。

1)在App\\Http\\Middleware\\Acl\\CheckPermission ,您需要将参数$permission = null替换'as'您在routes.php设置的'as'字符串。 新代码:

<?php namespace App\Http\Middleware;

use Closure;

class CheckPermission
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next/*, $permission = null REMOVE THIS*/)
    {
        // Add the next two lines:
        $action = $request->route()->getAction();
        $permission = isset($action['as']) ? $action['as'] : '';

        if (!app('Illuminate\Contracts\Auth\Guard')->guest()) {
            if ($request->user()->can($permission)) {
                return $next($request);
            }
        }

        return $request->ajax ? response('Unauthorized.', 401) : redirect('/login');
    }
}

2)现在,您需要以不同的方式分配此中间件。 您不想使用特定权限,而是使用我们刚刚在中间件中设置的'as'字符串。 您可以通过两种不同的方式分配中间件:a)将其分配给一组路由,或b)将其分配给每个页面。 我建议使用2a而不是2b,因为您可能不想在所有路由上使用ACL。

2a)这是将其分配给一组路线的方法。 这里需要注意的两个重要事项是'as'=>'clients.*'字符串以及将中间件分配给路由组'middleware' => 'acl' 另请注意,此路由组不会像教程那样传递额外的字符串参数(例如'middleware' => 'acl:manage_user' )。 这是因为我们从上面的handle()函数中删除了该参数。 您需要更改这些示例路由以匹配目标URI和控制器功能。

Route::group(['middleware' => 'acl'], function()
{
    Route::get('/clients', ['as'=>'clients.view', 'uses'=>'ClientsController@index']);
    Route::get('/clients/new', ['as'=>'clients.create', 'uses'=>'ClientsController@create']);
    // Add more routes ...
}

2b)以下是如何将其分配给每个页面。 本教程使用文件/app/Http/Kernel.php将中间件设置为$routeMiddleware 这是在上面的步骤2a中执行此操作的正确方法,但如果您希望在每个页面上执行此操作,则不会这样做。 要使中间件成为全局中间件:将'\\App\\Http\\Middleware\\CheckPermission'到同一文件中找到的$middleware变量中。 如果使用全局变量,则不需要从教程中添加$routeMiddleware

3)在教程数据库中,您需要在permission_slug列的permissions表中使用'as'字符串。 以下是允许id为123用户访问路由clients.create示例SQL插入。 这两个创建了我们创建访问'client.create'路径所需的权限和角色。

INSERT INTO permissions ('permission_title', 'permission_slug', 'permission_description')
    VALUES ('Create a Client', 'clients.create', 'Allow the user to create a client');

INSERT INTO roles ('role_title', 'role_slug')
    VALUES ('Client Admin', 'clients.admin');

对于下一个查询,您需要知道上面两行的id 这假设您的数据库是新创建的,但尚未添加任何行,因此每个插入都将为id=1 这表示: id=1权限被分配给id=1角色。

INSERT INTO permission_role ('permission_id', 'role_id') VALUES (1, 1);

下一个查询还假定新角色为id=1且用户ID为123 这会将id=1的新角色分配给id=123的现有用户。

INSERT INTO role_user ('role_id', 'user_id') VALUES (1, 123);

此时,您应该拥有id=123具有Client Admin角色的用户。 Client Admin角色应具有'clients.create'权限。 当您以用户id=123登录时,将验证您是否具有'clients.create'权限,并且您应该能够访问该页面(在我的示例中为example.com/clients/new )。 任何其他用户都无法访问,他们将被重定向到登录页面(如果您已经登录,这对我没有意义;这正是教程设置的内容)。

我建议你不要自己建立acl,那里有一些好的包,比如委托

如果你真的想知道原理或laravel acl只是按照laracast laracast laravel acl教程的视频教程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM