底线是:你需要在访问控制列表(ACL)中设置“list”。个人认为,最灵活的方式是基于会话用户从数据库中提取此列表;你已经有了良好的开端。您可以通过使用在路由中定义的已分配的
“as”
来跳过显式路由分配。例如路由:
Route::get('/', ['as'=>'clients.create', 'uses'=>'ClientsController@create']);
在这里,您将在ACL检查中使用'clients.create'
。只需记住:所有路由都需要设置'as'
值(这样做也很好)。
逐步指南
现在您已经获得了所需的背景信息,接下来是如何使其正常工作的方法。这些步骤假设您能够正确设置教程代码和数据库。这将坚持原始的教程设置,并专注于使ACL独立于路由配置。
1)在App\Http\Middleware\Acl\CheckPermission
中,您需要将参数$permission = null
替换为在routes.php
中设置的'as'
字符串。新代码:
<?php namespace App\Http\Middleware;
use Closure;
class CheckPermission
{
public function handle($request, Closure $next)
{
$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']);
}
2b)以下是如何将其分配给每个页面的方法。本教程使用文件/app/Http/Kernel.php
来设置中间件作为$routeMiddleware
。这是在步骤2a中正确的方法,但如果您想将其应用于每个页面,则不是正确的方法。要将中间件设置为全局中间件:请将'\App\Http\Middleware\CheckPermission'
添加到同一文件中找到的$middleware
变量中。如果使用全局变量,则无需使用教程中的$routeMiddleware
添加。
3) 在教程数据库中,您需要在permissions
表中的permission_slug
列中使用字符串'as'
。以下是示例SQL插入,允许具有id 123
的用户访问路径clients.create
。这两个创建了我们需要创建对'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的用户,并拥有"客户管理员"角色。 "客户管理员"角色应该拥有"clients.create"权限。当您以id为123的用户身份登录时,您将被验证是否具有"clients.create"权限,并且您应该能够访问页面(例如,在我的示例中是example.com/clients/new)。任何其他用户将无法访问该页面,并将被重定向到登录页面(如果您已经登录,则这没有意义;这只是教程设置的一部分)。