下面就laravel的内置ACL是如何工作的tutorial之后,我尝试过了,它通过自身定义每条路由效果很好。
现在,我尝试使用资源,但按照预期它不工作。我下面的代码添加到我的路线文件:
Route::group(['middleware' => 'acl:create_client'], function()
{
Route::resource('clients', 'ClientController');
});
现在我明白了是什么问题:
在Clientcontroller所有的方法都反对我的数据库来检查这个用户是否拥有ACL:create_client,导致登录具有此ACL用户可用的所有方法。
我如何拆分每次使用它自己的ACL,而不必把它写这样的方法:
Route::get('/client/create', [
'middleware' => 'acl:create_client',
'as' => 'clients.create',
'uses' => 'ClientController@create'
]);
导致这样的事情:
创造需求create_client
索引需要index_client
更新要update_client
等等等等。
底线是:你需要设置的访问控制列表(ACL)以某种方式“列表”。 IMO,最灵活的方式将拉基于会话用户数据库此列表;你有了一个良好的开端。您可以使用您在路由定义已分配'as'
跳过显式路由分配。一个例子路线:
Route::get('/', ['as'=>'clients.create', 'uses'=>'ClientsController@create']);
在这里,你将使用'clients.create'
在ACL检查。请记住:在ACL将仍然需要的所有路由设置'as'
值(这是很好的做反正)。
一步步
现在,你有必要的背景信息,这里是如何得到它的工作。这些步骤假定您能够正确安装教程代码和数据库。这将坚持原来的教程设置和将注重于独立于路由配置的ACL。
1)在App\Http\Middleware\Acl\CheckPermission
,你将需要更换与您在$permission = null
设置'as'
字符串参数routes.php
。新的代码:
<?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)在本教程中的数据库,你需要使用'as'
字符串中的permissions
表permission_slug
列中。这里有例如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
作用Client Admin
用户。该Client Admin
角色应该有'clients.create'
权限。当你登录的用户id=123
,你将被验证有'clients.create'
许可,您应该能够访问该页面(example.com/clients/new
在我的例子)。任何其他用户将无法访问,他们将被重定向到登录页面(这没有任何意义,我如果你已经登录,这正是本教程的设置)。
我建议你不要自行建立ACL,也有一些很好的包在那里像entrust
如果你真的想知道的原则或laravel ACL是追踪laracast laracast laravel acl tutorial这个视频教程