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');
Entrust是一种为Laravel5添加基于角色的权限的简洁而灵活的方法。的更多相关文章
- 项目:rbac 基于角色的权限管理系统;
- 简单示意流程图 - RBAC分析: - 基于角色的权限管理: - 权限等于用户可以访问的URL: - 通过限制URL来限制权限: - RBAC表结构组成: from django.db impor ...
- ASP.NET MVC 基于角色的权限控制系统的示例教程
上一次在 .NET MVC 用户权限管理示例教程中讲解了ASP.NET MVC 通过AuthorizeAttribute类的OnAuthorization方法讲解了粗粒度控制权限的方法,接下来讲解基于 ...
- C 实现基于角色的权限系统
本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1068 实例使用C# 实现基于角色的权限 ...
- SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建
SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建 技术栈 : SpringBoot + shiro + jpa + freemark ,因为篇幅原因,这里只 ...
- RBAC基于角色的权限访问控制
RBAC是什么,能解决什么难题?ThinkPHP中RBAC实现体系安全拦截器认证管理器访问决策管理运行身份管理器ThinkPHP中RBAC认证流程权限管理的具体实现过程RBAC相关的数据库介绍Th ...
- RBAC: K8s基于角色的权限控制
文章目录 RBAC: K8s基于角色的权限控制 ServiceAccount.Role.RoleBinding Step 1:创建一个ServiceAccount,指定namespace Step 2 ...
- Asp.net core IdentityServer4与传统基于角色的权限系统的集成
写在前面 因为最近在忙别的,好久没水文了 今天来水一篇: 在学习或者做权限系统技术选型的过程中,经常有朋友有这样的疑问 : "IdentityServer4的能不能做到与传统基于角色的权限系 ...
- 10.spring-boot基于角色的权限管理页面实现
10.spring-boot基于角色的权限管理页面实现
- webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制
webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...
随机推荐
- 第六篇 SQL Server安全执行上下文和代码签名
本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...
- WPF程序只运行一个实例
1.WPF程序在 启动窗口的构造函数执行InitializeComponent之前判断是否已经存在实例 不涉及服务器情况,可直接进行判断(不在mainwindow的构造函数中判断) // public ...
- .Net内存优化的几点经验
以前从来没有想过.Net开发居然存在内存无法释放的问题,总是认为GC给我处理好了一切.现在GIS二次开发结合三维球开发,没有想到存在如此严重的内存增长,很快内存就不够用了,导致系统各种不稳定.球体和三 ...
- css3实现动画效果
一.动画效果的常用属性 实现动画效果需要借助css3的下列属性:transform,transion,animation(具体可以参见教材) 二.动画效果实例 1)文字闪烁的动画效果 /*文字的闪烁效 ...
- iOS的三种多线程技术NSThread/NSOperation/GCD
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...
- C#线程系列讲座(4):同步与死锁
虽然线程可以在一定程度上提高程序运行的效率,但也会产生一些副作用.让我们先看看如下的代码: class Increment { private int n = 0; ...
- 做IT不能一辈子只靠技术生存
在中国你千万不要以为学习技术就可以换来稳定的生活和高的薪水待遇,你千万更不要认为哪些从事市场开发,跑腿的人,没有前途. 不知你是不是知道,咱们中国有相当大的一部分软件公司,他们的软件开发团队都小的可怜 ...
- jquery对strutrs2 <s:radio>标签的设置和取值
今天郁闷了1小时. 需求是这样的: <s:radio list="#{0:'男',1:'女'}" value="member.sex" id=" ...
- Java基础之一组有用的类——生成日期和时间(TryDateFormats)
控制台程序. java.util包中含有相当多的类涉及日期和时间,包括Date类.Calendar类和GregorianCalendar类. Date类对象其实定义了精确到毫秒的时刻,从1970年1月 ...
- 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes
表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...