Entrust是一種為Laravel5添加基於角色的權限的簡潔而靈活的方法。


安裝

首先要在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');


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM