laravel 多角色登录entrust 下怎么删除角色

在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
Entrust 帮助在 Laravel 中使用角色权限(Role)。
github地址:
安装使用中,会遇到的问题:This cache store does not support tagging.()
0 收藏&&|&&0
你可能感兴趣的文章
2 收藏,2.6k
6 收藏,2.9k
16 收藏,6.1k
分享到微博?
我要该,理由是:你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
刚学L5,如题,如果大伙有更好的权限插件推荐,求推荐!
我什么都没有用
2个都是很好的身份认证插件,推荐2个都试用一下就知道了
sentry用了下,感觉有点高不成低不就的感觉,比自带Auth 认证多了组管理和其他的一些。
当时做的东西比较小,只用了Auth,自己在user的模型里实现了isAdmin 和isSuper 方法。
sentry好像实现了一部分的基于角色的权限管理,用起来还是感觉不舒服。
l4的时候我用了sentry,框架更新到l5之后,用了一下entrust感觉这个插件没有sentry好用,不过每个人写代码的习惯可能会不一样,所以,最好是自己写几个demo感觉一下
Sentry $remember怎么用?
用了自带的Auth
要回复问题请先或
浏览: 8582
关注: 9 人Posts - 390,
Articles - 0,
Comments - 960
-正确的时间经历正确的事情
10:08 by 轩脉刃, ... 阅读,
关于权限管理的思考
最近用laravel设计后台,后台需要有个权限管理。权限管理实质上分为两个部分,首先是认证,然后是权限。认证部分非常好做,就是管理员登录,记录session。这个laravel中也有自带Auth来实现这个。最麻烦就是权限认证。
权限认证本质上就是谁有权限管理什么东西。这里有两个方面的维度,谁,就是用户维度,在用户维度,权限管理的粒度可以是用户一个人,也可以是将用户分组,如果将用户分组,则涉及到的逻辑是一个用户可以在多个组里面吗?在另外一方面,管理什么东西,这个东西是物的维度,一个页面是一个东西,一个页面上的一个元素也是一个东西,或者往大了说,一个功能是一个东西。所以做权限管理最重要的是确认这两个维度的粒度。这个已经不是技术的事情了,这个是需要需求讨论的了。
基于上面的思考,我这次想做的权限管理,在用户维度,是基于个人的。就是每个人的权限不一样。在东西的维度,我设置路由为最小的单位,即可以为单个路由设置权限管理。
下面的思考就是使用什么来标记权限,可以使用位,也可以使用字符,也可以使用整型。后来我选择了字符,基于两点考虑:1 字符浅显易懂,在数据库中查找也比较方便 2 我没有按照某个权限查找有这个权限的人的需求,即没有反查需求,使用位,整型等都意义不大。
接下来考虑如何和laravel结合,既然要为每个路由设置访问权限,那么我当然希望能在laravel的route.php路由管理中配置。最好就是在Route::get的时候有个参数能设置permission。这样做的好处是权限设置简易了。在决定路由的时候,就顺手写了权限控制。坏处呢,也很明显,laravel路由的三种方式只能写一种了。就是Route::(method)这样的方式了。
基本决定好了就开干。
基本的路由是这样的
Route::post('/admin/validate', ['uses' =& 'AdminController@postValidate', 'permissions'=&['admin.validate', 'admin.index']]);
这里在基本的制定路由action之后设置了一个permissions的属性,这个属性设计成数组,因为比如一个post请求,它可能在某个页面会触发,也可能在另外一个页面触发,那么这个post请求就需要同时拥有两个页面路由的权限。
这里使用admin.validate的权限控制,这样,可以将权限分组,admin都是关于admin相关的分组,在数据库中,我就会存储一个二维数组,[admin] =& ['validate', 'index']; 存储成二维数组而不是一维的好处呢,一般后台展示是有两个维度的,一个是头部的tab栏,一个是左边的nav栏,就是说这个二维的数组和后台的tab,nav栏是一一对应的。
中间件设计
好了,下面我们就挂上中间件,并且设置所有的路由都走这个中间件
&?php namespace App\Http\M
use Illuminate\Support\Facades\S
class Permission {
* Handle an incoming request.
\Illuminate\Http\Request
* @return mixed
public function handle($request, Closure $next)
$permits = $this-&getPermission($request);
$admin = \App\Http\Middleware\Authenticate::getAuthUser();
// 只要有一个有权限,就可以进入这个请求
foreach ($permits as $permit) {
if ($permit == '*') {
return $next($request);
if ($admin-&hasPermission($permit)) {
return $next($request);
echo &没有权限,请联系管理员&;
// 获取当前路由需要的权限
function getPermission($request)
$actions = $request-&route()-&getAction();
if (empty($actions['permissions'])) {
echo &路由没有设置权限&;
return $actions['permissions'];
这里最关键的就getPermission函数,从$request-&route()-&getAction()来获取出这个路由的action定义,然后从其中的permissions字段中获取route.php中定义的路由权限。
然后上面的middleware有个\(admin-&hasPermission(\)permit); 这个就涉及到model的设计。
&?php namespace App\Models\A
use App\Models\Model as BaseM
class Admin extends BaseModel {
protected $table = 'admin';
// 判断是否有某个权限
public function hasPermission($permission)
$permission_db = $this-&
if(in_array($permission, $permission_db)) {
// permission 是一个二维数组
public function getPermissionsAttribute($value)
if (empty($value)) {
return [];
$data = json_decode($value, true);
$ret = [];
foreach ($data as $key =& $value) {
$ret[] = $
foreach ($value as $value2) {
$ret[] = &{$key}.{$value2}&;
return array_unique($ret);
// 全局设置permission
public function setPermissionsAttribute($value)
$ret = [];
foreach ($value as $item) {
$keys = explode('.', $item);
if (count($keys) != 2) {
$ret[$keys[0]][] = $keys[1];
$this-&attributes['permissions'] = json_encode($ret);
在数据库中,我将二维数组存储为json,利用laravel的Attribute的get和set方法,完成了数据库中json和外界程序逻辑的连接。然后hasPermission就显得很轻松了,直接判断in_array就ok了。
这个权限认证的逻辑就清晰了。然后如果页面中某个tab或者nav需要对不同权限的用户展示,只需要在view中判断
@if ($admin-&hasPermission('admin.index'))
就可以判断这个用户是否可以看到这个tab了。
这个是一个不算复杂的用户权限实现,但是我感觉已经能满足大部分的后台需求了。当然可以优化的点可能很多,
比如permission是不是可以支持正则,hasPermission如果存储在nosql或者pg中,是不是不用进行json的数据解析,直接一个DB请求就能判断是否有permission之类的?首先要在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 - 存储角色和权限之间多对多关联
使用下面的示例创建app/models/Role.php作为角色模型:
&?phpnamespace Ause Zizaco\Entrust\EntrustRclass 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作为权限模型:
&?phpnamespace A&use Zizaco\Entrust\EntrustPclass Permission extends EntrustPermission{}
权限模型拥有和角色模型同样的三个主要属性:
1. name - 唯一的权限名称,用于在应用层查找权限信息。例如"create-post",“edit-user”,“post-payment”,“mailing-list-subscribe”。
2. display_name - 人类可读的权限名称。不一定是唯一和可选的。例如:“Create Post",“Post Payments”。
3. description - 权限的更多细节说明。
接着在User模型中使用EntrustUserTrait特征,示例:
&?phpuse Zizaco\Entrust\Traits\EntrustUserTclass User extends Eloquent{use EntrustUserT&// 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模板中有三个模板可以使用,你的参数将会被直接传递给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/advancedEntrust::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 accessEntrust::routeNeedsPermission('admin/post*', array('create-post', 'edit-comment'), null, false);// if a user is a member of 'owner', 'writer', or both they will have accessEntrust::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 PermissionEntrust::routeNeedsRoleOrPermission('admin/advanced*',array('owner', 'writer'),array('create-post', 'edit-comment'),null,false);
Entrust 的角色/权限过滤可以使用Facade:
Route::filter('manage_posts', function(){// check the current userif (!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 routeRoute::when('admin/post*', 'manage_posts');
使用过滤验证角色:
Route::filter('owner_role', function(){// check the current userif (!Entrust::hasRole('Owner')) {App::abort(403);}});// only owners will have access to routes within admin/advancedRoute::when('admin/advanced*', 'owner_role');
阅读(...) 评论()在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
1.laravel版本5.1安装entrust时,参照文档输入命令
php artisan entrust:migration
然后出现报错
求教如何解决
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
缓存标签目前不支持 file 或 database 缓存驱动,此外,当使用多标签的缓存被设置为永久存储时,使用memcached 驱动的缓存有着最佳性能表现,因为 Memcached 会自动清除陈旧记录 .所以.env中CACHE_DRIVER=file 改成 CACHE_DRIVER=memcached,
就可以了。我的是laravel 5.4,已经解决了这个问题
该答案已被忽略,原因:
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
首先,5.1 用坑很多,5.2我在官方的issues也看到很低级的问题,下面仅列举出来踩到的比较低级的坑
1) 就是你这个问题解决办法:修改文件:vendor/zizaco/entrust/src/commands/MigrationCommand.php 大约86行改为:
$usersTable
= Config::get('auth.table'); $userModel
= Config::get('auth.model');
官方解决了5.2有人提出的这个问题于是FIXED,又忽略了5.1,顾此失彼。
2) Trait method can has not been applied.解决办法:修改 Users 模型文件,去掉 implements 中的 AuthorizableContract 和 去掉 use 中的 Authorizable,因为和ACL冲突了
3) This cache store does not support tagging. 看这:
后面我放弃使用entust的想法,如果你继续使用应该你还会遇到一些问题,我个人是真担心真用上了发现了BUG发的那时间不如自己写一个,本人强迫症,绝对不会去修改vendor里的代码。
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:}

我要回帖

更多关于 laravel 角色 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信