joseph/rbac

此包提供了一种灵活的方式,可以将基于角色的权限添加到Laravel 4

v1.0 2014-05-31 19:10 UTC

This package is not auto-updated.

Last update: 2024-09-28 17:12:28 UTC


README

Rbac是rbac的副本,根据我的需求进行了修改,提供了一种灵活的方式,可以将基于角色的权限添加到Laravel4

所需设置

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

"joseph/rbac": "v1.0"

运行Composer更新命令

$ composer update

config/app.php中,将'Joseph\Rbac\RbacServiceProvider'添加到$providers数组末尾

'providers' => array(

    'Illuminate\Foundation\Providers\ArtisanServiceProvider',
    'Illuminate\Auth\AuthServiceProvider',
    ...
    'Joseph\Rbac\RbacServiceProvider',

),

config/app.php的末尾添加'Rbac' => 'Joseph\Rbac\RbacFacade'$aliases数组

'aliases' => array(

    'App'        => 'Illuminate\Support\Facades\App',
    'Artisan'    => 'Illuminate\Support\Facades\Artisan',
    ...
    'Rbac'    => 'Joseph\Rbac\RbacFacade',

),

配置

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

用户与角色之间的关系

现在生成Rbac迁移

$ php artisan rbac:migration

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

$ php artisan migrate

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

模型

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

<?php

use Joseph\Rbac\RbacRole;

class Role extends RbacRole
{

}

Role模型有一个主要属性:namepermissionsname,正如你可以想象的,是角色的名称。例如:"Admin"、"Owner"、"Employee"。permissions字段已被弃用,建议使用权限表。你不再使用它。它是一个数组,在模型保存时会自动序列化和反序列化。此数组应包含Role的权限名称。例如:array( "manage_posts", "manage_users", "manage_products" )

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

<?php

use Joseph\Rbac\RbacPermission;

class Permission extends RbacPermission
{

}

Permission模型有两个属性:namedisplay_namename,正如你可以想象的,是权限的名称。例如:"Admin"、"Owner"、"Employee"、"can_manage"。显示名称是权限字符串的观众友好版本。"Admin"、"Can Manage"、"Something Cool"。

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

<?php

use Joseph\Rbac\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 autoload

$ 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','=','Joseph')->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,因为用户是管理员并且具有 manage_posts 权限。

第三个参数是选项数组。

$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.
Rbac::routeNeedsPermission( 'admin/post*', 'manage_posts' );

// Only owners will have access to routes within admin/advanced
Rbac::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.
Rbac::routeNeedsPermission( 'admin/post*', array('manage_posts','manage_comments') );

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

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

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

进一步,这两种方法都接受第四个参数。它默认为 true,并检查所有给定角色/权限。如果将其设置为 false,则函数只有在所有角色/权限对用户都失败时才会失败。对于希望允许多个组访问的应用程序非常有用。

// If a user has `manage_posts`, `manage_comments` or both they will have access.
Rbac::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.
Rbac::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.
Rbac::routeNeedsRoleOrPermission( 'admin/advanced*', array('Owner','Writer'), array('manage_posts','manage_comments'), null, false);

路由过滤器

可以通过在 Facade 中使用 canhasRole 方法简单地使用 Rbac 角色权限在过滤器中。

Route::filter('manage_posts', function()
{
    if (! Rbac::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 (! Rbac::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'); 

如你所见,Rbac::hasRole()Rbac::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)

名称保存有问题。

RbacRolename 有一个长度限制,该限制在 RbacRole 类 的规则变量中设置。

您可以通过更改您的角色模型来调整它。

<?php

use Joseph\Rbac\RbacRole;

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

许可协议

Rbac 是免费软件,根据 MIT 许可协议分发

附加信息

如有任何问题,请随时联系我或在 这里 提问

如有任何问题,请 在此处报告