dcn/rbac

此包已废弃,不再维护。未建议替代包。

适用于 Laravel 5.1 的强大 RBAC 包

2.0 2017-01-05 01:38 UTC

This package is not auto-updated.

Last update: 2020-02-07 16:07:25 UTC


README

请参见 https://github.com/mbm-rafal/RBAC 代替!

RBAC For Laravel 5.3

用于处理 Laravel 5.3 中角色和权限的强大包

基于 Bican/Roles 包。

那么有什么不同?

不同之处在于 继承 的工作方式。在 Bican/Roles 中,权限根据您的最高 角色级别 进行继承。

而此包使用 parent_id 列来实现角色之间的继承。

这使得我们只能获取我们用户继承的角色的权限,或者直接分配给用户的权限。

安装

此包设置非常简单。只需几个步骤。

Composer

通过 Composer(文件 composer.json)引入此包。

{
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.1.*",
        "dcn/rbac": "~2.0"
    }
}

在终端中运行此命令。

composer update

服务提供者

将包添加到 config/app.php 文件中的应用程序服务提供者中。

'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    Illuminate\Foundation\Providers\ArtisanServiceProvider::class,
    Illuminate\Auth\AuthServiceProvider::class,
    ...

    /**
     * Third Party Service Providers...
     */
    DCN\RBAC\RBACServiceProvider::class,

],

配置文件和迁移

将包的配置文件和迁移发布到您的应用程序中。在终端中运行这些命令。

php artisan vendor:publish --provider="DCN\RBAC\RBACServiceProvider" --tag=config
php artisan vendor:publish --provider="DCN\RBAC\RBACServiceProvider" --tag=migrations

并运行迁移。

php artisan migrate

必须创建用于用户表的迁移文件,该文件是 Laravel 默认提供的。

HasRoleAndPermission 特性和契约

包含 HasRoleAndPermission 特性和在您的 User 模型中实现 HasRoleAndPermission 契约。

use DCN\RBAC\Traits\HasRoleAndPermission;
use DCN\RBAC\Contracts\HasRoleAndPermission as HasRoleAndPermissionContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract, HasRoleAndPermissionContract
{
    use Authenticatable, CanResetPassword, HasRoleAndPermission;

这就完成了!

使用方法

创建角色

use DCN\RBAC\Models\Role;

$adminRole = Role::create([
    'name' => 'Admin',
    'slug' => 'admin',
    'description' => '', // optional
    'parent_id' => NULL, // optional, set to NULL by default
]);

$moderatorRole = Role::create([
    'name' => 'Forum Moderator',
    'slug' => 'forum.moderator',
]);

由于 Slugable 特性,如果您在 slug 参数中出错,例如留下空格,它将被自动替换为点,因为使用了 str_slug 函数。

附加和分离角色

这非常简单。您从数据库中获取一个用户,并调用 attachRole 方法。在 UserRole 模型之间存在 BelongsToMany 关系。

use App\User;

$user = User::find($id);

$user->attachRole($adminRole); //you can pass whole object, or just an id
$user->detachRole($adminRole); // in case you want to detach role
$user->detachAllRoles(); // in case you want to detach all roles

拒绝角色

要拒绝用户一个角色及其所有子角色,请参阅以下示例。

如果您计划使用此功能,我们建议您相应地规划您的角色。因为您可能会在不经意间锁定用户。

use App\User;

$role = Role::find($roleId);

$user = User::find($userId);
$user->attachRole($role, FALSE); // Deny this role, and all of its decedents to the user regardless of what has been assigned.

检查角色

您现在可以检查用户是否有所需的角色。

if ($user->roleIs('admin')) { // you can pass an id or slug
    //
}

您也可以这样做

if ($user->isAdmin()) {
    //
}

当然,还有一种方法来检查多个角色

if ($user->roleIs('admin|moderator')) { // or $user->roleIs('admin, moderator') and also $user->roleIs(['admin', 'moderator'])
    // if user has at least one role
}

if ($user->roleIs('admin|moderator', true)) { // or $user->roleIs('admin, moderator', true) and also $user->roleIs(['admin', 'moderator'], true)
    // if user has all roles
}

以及通配符

if ($user->roleIs('admin|moderator.*')) { // or $user->roleIs('admin, moderator.*') and also $user->roleIs(['admin', 'moderator.*'])
    //User has admin role, or a moderator role
}

创建权限

多亏了 Permission 模型,这非常简单。

use DCN\RBAC\Models\Permission;

$createUsersPermission = Permission::create([
    'name' => 'Create users',
    'slug' => 'create.users',
    'description' => '', // optional
]);

$deleteUsersPermission = Permission::create([
    'name' => 'Delete users',
    'slug' => 'delete.users',
]);

附加和分离权限

您可以将权限附加到角色或直接附加到特定用户(当然也可以分离它们)。

use App\User;
use DCN\RBAC\Models\Role;

$role = Role::find($roleId);
$role->attachPermission($createUsersPermission); // permission attached to a role

$user = User::find($userId);
$user->attachPermission($deleteUsersPermission); // permission attached to a user
$role->detachPermission($createUsersPermission); // in case you want to detach permission
$role->detachAllPermissions(); // in case you want to detach all permissions

$user->detachPermission($deleteUsersPermission);
$user->detachAllPermissions();

拒绝权限

您可以拒绝用户一个权限,或者您也可以拒绝整个角色一个权限。

为此,在附加权限时,只需简单地传递第二个参数为 false。这将拒绝用户该权限,无论他们被分配了什么。拒绝的权限优先于继承和授予的权限。

use App\User;
use DCN\RBAC\Models\Role;

$role = Role::find($roleId);
$role->attachPermission($createUsersPermission, FALSE); // Deny this permission to all users who have or inherit this role.

$user = User::find($userId);
$user->attachPermission($deleteUsersPermission, FALSE); // Deny this permission to this user regardless of what roles they are in.

检查权限

if ($user->may('create.users') { // you can pass an id or slug
    //
}

if ($user->canDeleteUsers()) {
    //
}

您可以像检查角色一样检查多个权限。

继承

如果您不想在您的应用程序中使用继承功能,只需在创建角色时忽略 parent_id 参数即可。

分配给其他角色的 parent_id 的角色在用户分配或继承父角色时会自动继承。

以下是一个示例

您有5个管理组。管理员、商店管理员、商店库存管理员、博客管理员和博客作家。

角色 父级
管理员
商店管理员 管理员
商店库存管理员 商店管理员
博客管理员 管理员
博客作家 博客管理员

管理员角色商店管理员角色博客管理员角色 的父级。

商店管理员角色商店库存管理员角色 的父级。

博客管理员角色博客作家 的父级。

这使得 管理员角色 可以继承 商店库存管理员角色博客作家角色

商店管理员角色 只继承 商店库存管理员角色

博客管理员角色 只继承 博客作家角色

另一个示例

id slug parent_id
1 admin NULL
2 admin.user 1
3 admin.blog 1
4 blog.writer 3
5 development NULL

在这里,admin 继承了 admin.useradmin.blogblog.writer

admin.user 不继承任何内容,而 admin.blog 继承了 blog.writer

没有内容继承 development,而 development 也不继承任何内容。

实体检查

假设您有一篇文章并想编辑它。这篇文章属于一个用户(文章表中有一个 user_id 列)。

use App\Article;
use DCN\RBAC\Models\Permission;

$editArticlesPermission = Permission::create([
    'name' => 'Edit articles',
    'slug' => 'edit.articles',
    'model' => 'App\Article',
]);

$user->attachPermission($editArticlesPermission);

$article = Article::find(1);

if ($user->allowed('edit.articles', $article)) { // $user->allowedEditArticles($article)
    //
}

此条件检查当前用户是否是文章的所有者。如果不是,它将在用户权限中查找我们之前创建的行。

if ($user->allowed('edit.articles', $article, false)) { // now owner check is disabled
    //
}

Blade 扩展

有三种Blade扩展。基本上,它是对经典if语句的替代。

@role('admin') // @if(Auth::check() && Auth::user()->roleIs('admin'))
    // user is admin
@endrole

@permission('edit.articles') // @if(Auth::check() && Auth::user()->may('edit.articles'))
    // user can edit articles
@endpermission

@allowed('edit', $article) // @if(Auth::check() && Auth::user()->allowed('edit', $article))
    // show edit button
@endallowed

@role('admin|moderator', 'all') // @if(Auth::check() && Auth::user()->roleIs('admin|moderator', 'all'))
    // user is admin and also moderator
@else
    // something else
@endrole

中间件

此软件包包含VerifyRoleVerifyPermission中间件。您必须在app/Http/Kernel.php文件中添加它们。

/**
 * The application's route middleware.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'role' => \DCN\RBAC\Middleware\VerifyRole::class,
    'permission' => \DCN\RBAC\Middleware\VerifyPermission::class,
];

现在您可以轻松保护您的路由。

$router->get('/example', [
    'as' => 'example',
    'middleware' => 'role:admin',
    'uses' => 'ExampleController@index',
]);

$router->post('/example', [
    'as' => 'example',
    'middleware' => 'permission:edit.articles',
    'uses' => 'ExampleController@index',
]);

您还可以在VerifyPermissionVerifyRole中间件上传递多个参数,例如:role:admin,moderator,true,最后一个参数将用于确定用户是否拥有所有角色或只是传递的任一角色,默认值为false

如果出错,它将抛出\DCN\RBAC\Exception\RoleDeniedException\DCN\RBAC\Exception\PermissionDeniedException异常。

您可以在app/Exceptions/Handler.php文件中捕获这些异常并执行任何操作。

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    if ($e instanceof \DCN\RBAC\Exceptions\RoleDeniedException) {
        // you can for example flash message, redirect...
        return redirect()->back();
    }

    return parent::render($request, $e);
}

配置文件

您可以更改模型的连接、slug分隔符、模型路径,还有一个方便的模拟功能。请查看配置文件以获取更多信息。

更多信息

本项目基于Bican/Roles

许可证

此软件包是免费软件,根据MIT许可证的条款分发。

我不关心你如何使用它。

贡献

我老实说不知道我在做什么。如果你看到可以修复的内容,请在develop分支上提交一个pull request!