使用 Entrust 扩展包在 Laravel 5 中实现 RBAC 权限管理(一):安装配置篇

Entrust为我们在Laravel中实现基于角色的权限管理(RBAC)提供了简洁灵活的方式。

1、安装

想要在Laravel中使用Entrust,首先需要通过Composer来安装其依赖包:

composer require zizaco/entrust 5.2.x-dev

安装完成后需要在config/app.php中注册服务提供者到providers数组:

Zizaco\Entrust\EntrustServiceProvider::class,

同时在该配置文件中注册相应门面到aliases数组:

'Entrust' => Zizaco\Entrust\EntrustFacade::class,

如果你想要使用中间件(要求Laravel 5.1或更高版本)还需要添加如下代码到app/Http/Kernel.phprouteMiddleware数组:

'role' => \Zizaco\Entrust\Middleware\EntrustRole::class,
'permission' => \Zizaco\Entrust\Middleware\EntrustPermission::class,
'ability' => \Zizaco\Entrust\Middleware\EntrustAbility::class,

2、配置

在配置文件config/auth.php中设置合适的值,Entrust会使用这些配置值来选择相应的用户表和模型类:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
        'table' => 'users',
    ],
],

你还可以发布该扩展包的配置以便后续自定义相关表名以及模型类的命名空间:

php artisan vendor:publish

该命令会在config目录下创建一个entrust.php文件。

3、用户角色权限表

接下来我们使用Entrust提供的迁移命令生成迁移文件:

php artisan entrust:migration

然后通过以下命令生成相应的数据表:

php artisan migrate

最终会生成4张新表:

  • roles —— 存储角色
  • permissions —— 存储权限
  • role_user —— 存储角色与用户之间的多对多关系
  • permission_role —— 存储角色与权限之间的多对多关系

4、模型类

Role

我们需要创建Role模型类app/Role.php并编辑其内容如下:

<?php namespace App;

use Zizaco\Entrust\EntrustRole;

class Role extends EntrustRole
{
}

Role模型拥有三个主要属性:

  • name —— 角色的唯一名称,如“admin”,“owner”,“employee”等
  • display_name —— 人类可读的角色名,例如“后台管理员”、“作者”、“雇主”等
  • description —— 该角色的详细描述

display_namedescription属性都是可选的,在数据库中的相应字段默认为空。

Permission

接下来创建Permission模型app/Permission.php并编辑其内容如下:

<?php namespace App;

use Zizaco\Entrust\EntrustPermission;

class Permission extends EntrustPermission
{
}

Permission模型也有三个主要属性:

  • name —— 权限的唯一名称,如“create-post”,“edit-post”等
  • display_name —— 人类可读的权限名称,如“发布文章”,“编辑文章”等
  • description —— 该权限的详细描述

User

接下来我们在User模型中使用EntrustUserTrait

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;

class User extends Authenticatable
{
    use Notifiable;
    use EntrustUserTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

这将会建立UserRole之间的关联关系:在User模型中添加roles()hasRole($name)can($permission)以及ability($roles,$permissions,$options)方法。

软删除

使用Entrust提供的迁移命令生成的关联关系表中默认使用了onDelete('cascade')以便父级记录被删除后移除其对应的关联关系。如果你由于某种原因不能在数据库中使用级联删除,那么可以在EntrustRoleEntrustPermission类以及HasRole trait提供的事件监听器中手动删除关联表中的记录。如果模型使用了软删除,那么当不小心误删除数据时,事件监听器将不会删除关联表数据。不过,由于Laravel事件监听器的局限性,所以暂时无法区分是调用delete()还是forceDelete(),基于这个原因,在你删除一个模型之前,必须手动删除所有关联数据(除非你的数据表使用了级联删除):

$role = Role::findOrFail(1); // 获取给定权限

// 正常删除
$role->delete();

// 强制删除
$role->users()->sync([]); // 删除关联数据
$role->perms()->sync([]); // 删除关联数据

$role->forceDelete(); // 不管透视表是否有级联删除都会生效

下一节我们将来演示如何在Laravel中使用Entrust实现RBAC。

学院君 has written 984 articles

Laravel学院院长,终身学习者

积分:113677 等级:P12 职业:手艺人 城市:杭州

57 条回复

  1. jay0714 jay0714 says:
    @ Z.

    找到这个Zizaco\Entrust\MigrationCommand这个文件,然后里面又个fire方法改成handle方法即可

  2. Z. Z. says:

    生成迁移文件时报错 ReflectionException:方法Zizaco \ Entrust \ MigrationCommand :: handle() 不存在

  3. 暴躁小野猫 暴躁小野猫 says:
    数据库迁移 $ php artisan entrust:migration Tables: roles, role_user, permissions, permission_role A migration that creates 'roles', 'role_user', 'permissions', 'permission_role' tables will be created in database/migrations directory Proceed with the migration creation? [Yes|no] (yes/no) [yes]: > Creating migration... Migration successfully created! 只生成一个文件 只有一个role表是怎么回事
  4. 墨染堇年 墨染堇年 says:
    删除角色的时候 $role->delete(); 会报错 Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) Class name must be a valid object or a string 有没有大佬知道这是咋回事
  5. 任瑞东 任瑞东 says:
    我再生成php artisan entrust:migration 命令时提示 Class 'App\User' not found 我都已经设置好路径为什么还是报错呢
  6. guoqingyu guoqingyu says:
    你好我也遇到了同样的问题 请问解决了吗
  7. m m says:
    添加过滤器报错 Attribute [filter] does not exist. laravel5.4 大佬们怎么解决的
  8. 老改 老改 says:
    这个问题也是用在laravel5.5中才遇到的一个问。 这个提示也很明确,说是找不到这个方法, 所以解决办法就是找到这个Zizaco\Entrust\MigrationCommand这个文件,然后里面又个fire方法改成handle方法即可,
  9. 流失 流失 says:
    D:\phpStudy\WWW\blog>php artisan entrust:migration In BoundMethod.php line 135: Method Zizaco\Entrust\MigrationCommand::handle() does not exist 这是什么情况
  10. neil neil says:
    1.删除role角色数据的时候 $role=Role::findOrFail($id); $role->delete();出现这个错误。FatalErrorException in HasRelationships.php line 487: Class 'Badmin' not found。。2.给角色赋权限的时候。错误BadMethodCallException in Builder.php line 2443: Call to undefined method Illuminate\Database\Query\Builder::perms()。。。都是什么类找不到,方法找不到。怎么回事啊,完全按照上面步骤来的。。求科普

登录后才能进行评论,立即登录?