funfirst/entrust

此包提供了一种灵活的方式为Laravel 4添加基于角色的权限

1.3.0 2014-09-26 17:53 UTC

README

Entrust Poster

Build Status ProjectStatus

Entrust提供了一种灵活的方式为Laravel4添加基于角色的权限。

快速入门

注意:虽然不是必需的。Entrust与Confide配合使用非常好,以消除涉及用户管理的重复性任务:账户创建、登录、登出、电子邮件确认、密码重置等。

查看Confide

所需设置

composer.json文件的require键中添加以下内容

"zizaco/entrust": "1.2.*@dev"

运行Composer更新命令

$ composer update

在您的config/app.php中,将'Zizaco\Entrust\EntrustServiceProvider'添加到$providers数组的末尾

'providers' => array(

    'Illuminate\Foundation\Providers\ArtisanServiceProvider',
    'Illuminate\Auth\AuthServiceProvider',
    ...
    'Zizaco\Entrust\EntrustServiceProvider',

),

config/app.php的末尾添加'Entrust' => 'Zizaco\Entrust\EntrustFacade'$aliases数组中

'aliases' => array(

    'App'        => 'Illuminate\Support\Facades\App',
    'Artisan'    => 'Illuminate\Support\Facades\Artisan',
    ...
    'Entrust'    => 'Zizaco\Entrust\EntrustFacade',

),

配置

config/auth.php中设置属性值。这些值将被Entrust用来引用正确的用户表和模型。

用户与角色之间的关系

现在生成Entrust迁移

$ php artisan entrust:migration

它将生成<timestamp>_entrust_setup_tables.php迁移。您现在可以使用artisan migrate命令运行它

$ php artisan migrate

迁移之后,将出现两个新的表:包含现有角色及其权限的roles表和表示UserRole之间多对多关系的assigned_roles表。

模型

创建一个Role模型,遵循app/models/Role.php中的示例

<?php

use Zizaco\Entrust\EntrustRole;

class Role extends EntrustRole
{

}

Role模型有两个主要属性:namepermissionsname,如你所想,是角色的名称。例如:“管理员”,“所有者”,“员工”。permissions字段已被弃用,首选权限表。您不应再使用它。它是一个数组,在模型保存时自动序列化和反序列化。此数组应包含角色的权限名称。例如:array( "manage_posts", "manage_users", "manage_products" )

创建一个Permission模型,遵循app/models/Permission.php中的示例

<?php

use Zizaco\Entrust\EntrustPermission;

class Permission extends EntrustPermission
{

}

Permission模型有两个属性:namedisplay_namename,如你所想,是权限的名称。例如:“管理员”,“所有者”,“员工”,“can_manage”。display_name是权限字符串的面向观众的版本。“管理员”,“可以管理”,“很酷的东西”。

接下来,在您的现有User模型中使用HasRole特性。例如

<?php

use Zizaco\Entrust\HasRole;

class User extends Eloquent /* or ConfideUser 'wink' */{
    use HasRole; // Add this trait to your user model

...

这将实现与Role的关系,并在您的User模型中启用以下方法:roleshasRole( $name )can( $permission )ability($roles, $permissions, $options)

别忘了清除composer自动加载

$ composer dump-autoload

现在您可以开始了。

用法

概念

让我们首先创建以下RolePermission

$owner = new Role;
$owner->name = 'Owner';
$owner->save();

$admin = new Role;
$admin->name = 'Admin';
$admin->save();

接下来,创建了这两个角色后,让我们将它们分配给用户。多亏了HasRole特性,这很简单

$user = User::where('username','=','Zizaco')->first();

/* role attach alias */
$user->attachRole( $admin ); // Parameter can be an Role object, array or id.

/* OR the eloquent's original: */
$user->roles()->attach( $admin->id ); // id only

现在我们只需给这些角色添加权限。

$managePosts = new Permission;
$managePosts->name = 'manage_posts';
$managePosts->display_name = 'Manage Posts';
$managePosts->save();

$manageUsers = new Permission;
$manageUsers->name = 'manage_users';
$manageUsers->display_name = 'Manage Users';
$manageUsers->save();

$owner->perms()->sync(array($managePosts->id,$manageUsers->id));
$admin->perms()->sync(array($managePosts->id));

现在我们可以通过执行以下操作简单地检查角色和权限

$user->hasRole("Owner");    // false
$user->hasRole("Admin");    // true
$user->can("manage_posts"); // true
$user->can("manage_users"); // false

每个User可以有任意多的Role,反之亦然。

可以使用出色的ability函数进行更复杂的检查。它接受三个参数(角色、权限、选项)。roles是要检查的角色集。permissions是要检查的权限集。角色或权限变量可以是逗号分隔的字符串或数组。

$user->ability(array('Admin','Owner'), array('manage_posts','manage_users'));
//or
$user->ability('Admin,Owner', 'manage_posts,manage_users');

这将检查用户是否有提供的任何角色和权限。在这种情况下,它将返回true,因为用户是管理员,并且具有管理帖子的权限。

第三个参数是一个选项数组。

$options = array(
'validate_all' => true | false (Default: false),
'return_type' => boolean | array | both (Default: boolean)
);

validate_all是一个布尔标志,用于设置是否检查所有值是否为true,或者如果至少有一个角色或权限匹配,则返回true。

return_type指定是否返回布尔值、检查值的数组或以数组形式返回两者。

以下是一些示例输出。

$options = array(
'validate_all' => true,
'return_type' => 'both'
);
list($validate,$allValidations) = $user->ability(array('Admin','Owner'), array('manage_posts','manage_users'), $options);

// Output
var_dump($validate);
bool(false)
var_dump($allValidations);
array(4) {
  ['role']=>
  bool(true)
  ['role_2']=>
  bool(false)
  ['manage_posts']=>
  bool(true)
  ['manage_users']=>
  bool(false)
}

简短语法路由过滤器

要按权限或角色过滤路由,你可以在你的app/filters.php中调用以下内容

// Only users with roles that have the 'manage_posts' permission will
// be able to access any route within admin/post.
Entrust::routeNeedsPermission( 'admin/post*', 'manage_posts' );

// Only owners will have access to routes within admin/advanced
Entrust::routeNeedsRole( 'admin/advanced*', 'Owner' );

// Optionally the second parameter can be an array of permissions or roles.
// User would need to match all roles or permissions for that route.
Entrust::routeNeedsPermission( 'admin/post*', array('manage_posts','manage_comments') );

Entrust::routeNeedsRole( 'admin/advanced*', array('Owner','Writer') );

这两个方法都接受第三个参数。如果第三个参数为null,则禁止访问的返回将为App::abort(403)。否则,将返回第三个参数。所以你可以用它

Entrust::routeNeedsRole( 'admin/advanced*', 'Owner', Redirect::to('/home') );

此外,这两个方法还接受第四个参数。默认值为true,并检查所有提供的角色/权限。如果你将其设置为false,则函数只有在所有角色/权限对该用户失败时才会失败。对于希望允许多个组访问的admin应用程序非常有用。

// If a user has `manage_posts`, `manage_comments` or both they will have access.
Entrust::routeNeedsPermission( 'admin/post*', array('manage_posts','manage_comments'), 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 `manage_posts`, `manage_comments` they will have access.
// You can set the 4th parameter to true then user must be member of Role and must has Permission.
Entrust::routeNeedsRoleOrPermission( 'admin/advanced*', array('Owner','Writer'), array('manage_posts','manage_comments'), null, false);

路由过滤器

可以使用Entrust Facade中的canhasRole方法在过滤器中使用Entrust角色/权限。

Route::filter('manage_posts', function()
{
    if (! Entrust::can('manage_posts') ) // Checks the current user
    {
        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()
{
    if (! Entrust::hasRole('Owner') ) // Checks the current user
    {
        App::abort(404);
    }
});

// Only owners will have access to routes within admin/advanced
Route::when('admin/advanced*', 'owner_role');

如你所见,Entrust::hasRole()Entrust::can()检查用户是否已登录,然后检查他是否有该角色或权限。如果用户未登录,则返回值也将为false

故障排除

如果在迁移过程中遇到类似以下错误的错误

SQLSTATE[HY000]: General error: 1005 Can't create table 'laravelbootstrapstarter.#sql-42c_f8' (errno: 150) (SQL: alter table `assigned_roles` add constraint assigned_roles_user_id_foreign foreign key (`
  user_id`) references `users` (`id`)) (Bindings: array (
  ))

那么很可能是你的用户表中的id列与assigned_roles中的user_id列不匹配。确保两者都是INT(10)

名称保存有问题。

EntrustRole->name在EntrustRole类的规则变量中设置了长度限制。

你可以通过更改你的Role Model来调整它。

<?php

use Zizaco\Entrust\EntrustRole;

class Role extends EntrustRole
{
    /**
     * Ardent validation rules
     *
     * @var array
     */
    public static $rules = array(
      'name' => 'required|between:4,255'
    );
}

许可证

Entrust是在MIT许可证条款下免费软件。

附加信息

有任何问题,请随时联系我或在此提问

任何问题,请在此报告