安裝
首先要在composer.json中添加:
"zizaco/entrust": "5.2.x-dev"
然后運行composer install 或者 composer update
在 config.php的provider數組中添加:
Zizaco\Entrust\EntrustServiceProvider::class,
在config.php的alias數組中添加:
'Entrust'=>Zizaco\Entrust\EntrustFacade::class,
如果你要使用中間件(要求5.1或更高版本),你需要在app\Http\kernel.php的routeMiddleware數組中添加:
'role'=>\Zizaco\Entrust\Middleware\EntrustRole::class,
'permission'=>\Zizaco\Entrust\Middleware\EntrustPermission::class,
'ability'=>\Zizaco\Entrust\Middleware\EntrustAbility::class, 配置
在config/auth.php設置屬性值。這是值將被用於給entrust指定正確的用戶表和模型。
你也可以發布這個包的配置以便進一步的配置表明和命名空間。
只要使�php artisan vendor:publish , entrsust.php就會被創建到app/config文件夾中。
用戶關聯到角色
現在生成enrust遷移:
php artisan entrust:migration
這將生成<timestamp>_entrust_setup_tables.ph遷移。你這時可以使用遷移命令運行它了:
php artisan migrate
遷移結束后,會創建4張新表:
1. roles - 存儲角色記錄
2. permissions - 存儲權限記錄
3. role_user - 存儲角色與用戶之間多對多關聯
4. peimissionrole - 存儲角色和權限之間多對多關聯
模型 Role
使用下面的示例創建app/models/Role.php作為角色模型:
<?php
namespace App;
use Zizaco\Entrust\EntrustRole;
class Role extends EntrustRole{
}
角色模型有3個主要屬性:
1. name - 唯一的角色名稱,用於在應用信息層查找角色信息。例如:“admin”,“owner”,“employee”。
2. display_name - 人類可讀的角色名稱。不一定是唯一和可選的。“User Administrator”,“Project Owner”,“Widget Co.Employee”。
3. description - 關於角色作用更詳細的解釋。 同樣是可選的。
display_name 和 description同樣可選的。在數據庫中他們可以為空。
權限
使用下面的示例創建app/models/Permission.php作為權限模型:
<?php
namespace App;
use Zizaco\Entrust\EntrustPermission;
class Permission extends EntrustPermission{
}
權限模型擁有和角色模型同樣的三個主要屬性:
1. name - 唯一的權限名稱,用於在應用層查找權限信息。例如"create-post",“edit-user”,“post-payment”,“mailing-list-subscribe”。
2. display_name - 人類可讀的權限名稱。不一定是唯一和可選的。例如:“Create Post",“Post Payments”。
3. description - 權限的更多細節說明。
User
接着在User模型中使用EntrustUserTrait特征,示例:
<?php
use Zizaco\Entrust\Traits\EntrustUserTrait;
class User extends Eloquent{
use EntrustUserTrait;
// add this trait to your user model...
}
這會讓與角色的關系生效,並為你的User模型增加roles(), hasRole($name), can($permission), and ability($roles, $permissions, $options)這些方法。
不要忘記執行
composer dump-autoload 軟刪除
默認的遷移在父記錄被刪除時運用onDelete('cascade')子句設置以刪除關聯。如果由於某些原因在數據庫中你無法使用級聯刪除, EntrustRole和EntrustPermission類以及包含時間監聽器的HasRole特性可以手動地在相關數據透視表中刪除記錄。為了避免不小心刪除數據,在模型使用軟刪除的情況下,時間監聽器不會刪除實際數據。由於Laravel事件監聽器的限制,沒有任何辦法區分delete()和forceDelete()調用。由於這個原因,在你刪除這個模型之前,你必須手動地刪除任何相關的數據(除非你的數據透視表使用級聯刪除),例如:
$role=Role::findOrFail(1); // 取得一個給定的角色
// 常規刪除
$role->delete();
// 這無論如何都會工作
// 強制刪除
$role->users()->sync([]); // 刪除關聯數據
$role->perms()->sync([]); // 刪除關聯數據
$role->forceDelete(); // 現在強制刪除都會起作用,不管透視表是夠有級聯刪除
用法
概念
從創建下面的角色S和權限S開始:
$owner=newRole();
$owner->name='owner';
$owner->display_name='Project Owner'; // optional
$owner->description='User is the owner of a given project'; // optional
$owner->save();
$admin=newRole();
$admin->name='admin';
$admin->display_name='User Administrator'; // optional
$admin->description='User is allowed to manage and edit other users'; // optional
$admin->save();
接着,我們將兩個已經創建的角色分配給用戶。因為有了HasRole特性所以很容易:
$user=User::where('username', '=', 'michele')->first();
// 角色添加別名
$user->attachRole($admin); // 參數可以是角色項目,數組或者
// 或者 eloquent's 原來的技術
$user->roles()->attach($admin->id); // 僅ID
現在我們只需要給這些角色添加權限:
$createPost=newPermission();
$createPost->name='create-post';
$createPost->display_name='Create Posts'; // optional
// Allow a user to...
$createPost->description='create new blog posts'; // optional
$createPost->save();
$editUser=newPermission();
$editUser->name='edit-user';
$editUser->display_name='Edit Users'; // optional
// Allow a user to...
$editUser->description='edit existing users'; // optional
$editUser->save();
$admin->attachPermission($createPost);// equivalent to $admin->perms()->sync(array($createPost->id));
$owner->attachPermissions(array($createPost, $editUser));// equivalent to $owner->perms()->sync(array($createPost->id, $editUser->id));
驗證角色和權限
現在我們就可以用簡單的方法驗證角色和權限:
$user->hasRole('owner'); // false
$user->hasRole('admin'); // true
$user->can('edit-user'); // false
$user->can('create-post'); // true
hasRole()和can()都能接受一個角色和權限的數組用於驗證:
$user->hasRole(['owner', 'admin']); // true
$user->can(['edit-user', 'create-post']); // true
默認情況,任何角色或權限屬於當前用戶,方法就會返回為true。 將方法的第二個參數設置為true,就要求所有權限和角色都通過才能驗證成功
$user->hasRole(['owner', 'admin']); // true
$user->hasRole(['owner', 'admin'], true); // false, 用戶並沒有admin角色
$user->can(['edit-user', 'create-post']); // true
$user->can(['edit-user', 'create-post'], true); // false, 用戶沒有edit-user權限
你可以隨意為每個用戶分配任意多的角色,反之亦然。
Entrust為當前已經登錄的用戶准備了hasRole()和can()的快捷方式
Entrust::hasRole('role-name');
Entrust::can('permission-name');
// 等價於
Auth::user()->hasRole('role-name');
Auth::user()->can('permission-name);
你也可以使用占位符(通配符)驗證任何符合條件的權限:
// 匹配任意的admin權限
$user->can("admin.*"); // true
// 匹配任意關於用戶的權限
$user->can("*_users"); // true
用戶可用性
更多高級驗證可以使用ability函數。它有三個參數(roles,permissions,options):
1. roles 一組用於驗證的roles
2. permissions 一組用於驗證的peimissions
roles和peimissions變量可以是一組逗號分割的字符串或數組:
$user->ability(array('admin', 'owner'), array('create-post', 'edit-user'));
// or
$user->ability('admin,owner', 'create-post,edit-user');
這可以同時檢查用戶是否提供角色和權限。在這個例子中,只有當用戶是admin並且擁有create-post選前才會返回true.
第三個參數是一個可選數組:
$options = array(
'validate_all' => true | false (Default: false),
'return_type' => boolean | array | both (Default: boolean)
);
1. validate_all 這是一個boolean值用於設置是否驗證所有制都為true,或者當至少一個角色或權限匹配時返回true。
2. return_type 指定是否返回匹配值得boolean或數組,或者兩者都在一個數組中,
下面是輸出的示例:
$options = array(
'validate_all' => true,
'return_type' => 'both'
);
list($validate, $allValidations) = $user->ability(
array('admin', 'owner'),
array('create-post', 'edit-user'),
$options
);
var_dump($validate);
// bool(false)
var_dump($allValidations);
// array(4) {
// ['role'] => bool(true)
// ['role_2'] => bool(false)
// ['create-post'] => bool(true)
// ['edit-user'] => bool(false)
// }
Entrust為當前已登錄用戶准備了ability()方法的快捷方式
Entrust::ability('admin,owner', 'create-post,edit-user');
// 等同於
Auth::user()->ability('admin,owner', 'create-post,edit-user');
Blade模板
在Blade模板中有三個模板可以使用,你的參數將會被直接傳遞給Entrust的函數
@role('admin')
<p>這里對有admin角色的用戶可見. 會被翻譯為 \Entrust::role('admin')</p>
@endrole
@permission('manage-admins')
<p>這里對給定權限的用戶可見. 會被翻譯為 \Entrust::can('manage-admins').@can已經被laravel核心驗證包使用, 所以用 @permission直接代替.</p>
@endpermission
@ability('admin,owner', 'create-post,edit-user')
<p>這里對給定能力的用戶可見. 會被翻譯為 \Entrust::ability('admin,owner', 'create-post,edit-user')</p>
@endability
中間件
您可以使用中間件通過權限或角色來過濾路由和路由組:
Route::group(['prefix' => 'admin', 'middleware' => ['role:admin']], function() {
Route::get('/', 'AdminController@welcome');
Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']);
});
可以使用管道符號或操作符:
'middleware'=> ['role:admin|root']
模擬和功能化使用了多個中間件的實例:
'middleware'=> ['permission:owner', 'permission:writer']
更復雜的情況可以使用ability中間件,它包含三個參數:roles, permissions, validate_all
'middleware'=> ['ability:admin|owner,create-post|edit-user,true']
短語法路由過濾器
使用權限或角色過濾一個路由可以在你的app/Http/routes.php中使用如下代碼:
// 僅當用戶角色擁有'manage_posts'權限時才可以訪問admin/post路由
Entrust::routeNeedsPermission('admin/post*', 'create-post');
// 僅當owner角色可以訪問admin/advanced
Entrust::routeNeedsRole('admin/advanced*', 'owner');
// 第二份可選參數可以是權限或角色的數組
// 用戶需要滿足所有角色和權限的需求才可以訪問此數組
Entrust::routeNeedsPermission('admin/post*', array('create-post', 'edit-comment'));
Entrust::routeNeedsRole('admin/advanced*', array('owner','writer'));
這兩個方法都接受第3個參數,如果第三個參數為null就會返回一個App::abort(403)禁止訪問,否則返回第三個參數,所以你可以這樣使用:
Entrust::routeNeedsRole('admin/advanced*', 'owner', Redirect::to('/home'));
此外這兩種方法還接受第4個參數,默認為true,驗證所有給定的角色和權限。如果你設置為false,僅當所有權限和角色都驗證失敗時函數才會返回失敗。這對后台程序需要允許訪問多個組很有用:
// if a user has 'create-post', 'edit-comment', or both they will have access
Entrust::routeNeedsPermission('admin/post*', array('create-post', 'edit-comment'), null, false);
// if a user is a member of 'owner', 'writer', or both they will have access
Entrust::routeNeedsRole('admin/advanced*', array('owner','writer'), null, false);
// if a user is a member of 'owner', 'writer', or both, or user has 'create-post', 'edit-comment' they will have access
// if the 4th parameter is true then the user must be a member of Role and must have Permission
Entrust::routeNeedsRoleOrPermission(
'admin/advanced*',
array('owner', 'writer'),
array('create-post', 'edit-comment'),
null,
false
);
路由過濾
Entrust 的角色/權限過濾可以使用Facade:
Route::filter('manage_posts', function()
{
// check the current user
if (!Entrust::can('create-post')) {
return Redirect::to('admin');
}
});
// only users with roles that have the 'manage_posts' permission will be able to access any admin/post route
Route::when('admin/post*', 'manage_posts');
使用過濾驗證角色:
Route::filter('owner_role', function()
{
// check the current user
if (!Entrust::hasRole('Owner')) {
App::abort(403);
}
});
// only owners will have access to routes within admin/advanced
Route::when('admin/advanced*', 'owner_role');