uzzal/acl

Laravel 框架的动态配置权限

v3.0.0 2023-05-18 08:33 UTC

README

升级以支持 Laravel 8 及最新版本

Laravel 的动态配置访问控制。一个用户可以有多个角色。

安装

composer require uzzal/acl

配置

在你的 laravel config/app.php 下的 providers 中添加

Uzzal\Acl\AclServiceProvider::class

发布

artisan vendor:publish

此命令将发布位于 views/vendor/acl 的视图文件,位于 databases/seed 的种子文件以及配置文件 config/acl.php

数据库种子

database/seeds/DatabaseSeeder.php 下添加以下行

$this->call(UserTableSeeder::class); //optional        
$this->call(RoleTableSeeder::class);
$this->call(ResourceTableSeeder::class);
$this->call(PermissionTableSeeder::class);
$this->call(UserRoleTableSeeder::class);

注意:如果您看到任何类型的类未找到类型错误,请尝试运行 composer dump-autoload

Artisan 命令

此库包含一个 artisan 命令 acl:resource,用于自动创建位于 app/Http/Controllers 目录下的所有资源(控制器@操作)。要激活此命令,您需要将以下行添加到您的 app/Console/Kernel.php 文件中。

protected $commands = [
    Uzzal\Acl\Commands\AclResource::class
];

修改 User 模型

在您的 User 模型中添加以下特质

use Uzzal\Acl\Traits\AccessControlled;

class User extends Authenticatable
{    
    use AccessControlled;
    ...
}

#[Attribute]

Acl 库现在支持两种属性 #Resource#Authorize,用于与控制器操作一起使用

#[Authorize('Admin, Default')]
#[Resource('able to see home')]
public function index()
{
    return view('home');
}

注意:默认情况下,开发者 角色具有最高的权限级别,并且不需要在 #Authorize 属性中提及。如果您删除 #Authorize 属性,它不会从数据库中删除权限,但如果您更改注释中的角色列表,则会相应地更新数据库。

中间件

此 ACL 库包含以下两个中间件。您需要的是 AuthenticateWithAcl 中间件。另一个 ResourceMaker 中间件只是用于在最初不存在的情况下动态创建资源并为 developer 角色分配权限的辅助工具。

在您的 kernal.php 文件中添加以下行

'auth.acl' => \Uzzal\Acl\Middleware\AuthenticateWithAcl::class,        
'resource.maker' => \Uzzal\Acl\Middleware\ResourceMaker::class,

在您的 route/web.php 文件中添加以下行

Route::group(['middleware' => ['resource.maker','auth.acl']], function () {    
    Route::get('/home', 'HomeController@index');    
});

重要:必须将 resource.maker 放在 auth.acl 之前。在生产中,一旦所有资源都已生成,您可以删除 resource.maker

角色 & 资源 UI

要访问角色,请访问 YOUR-HOST/role URL

要访问资源 UI,请访问 YOUR-HOST/resource URL

访问检查

有几种方法可以检查访问权限

通过路由名称,这里 home.index 是路由的名称。

if (allowed('home.index')) {
    echo "will allow here if the user has access";
}

// alternatively in blade template

@allowed('home.index')
<h4>Will be visible if the user has permission</h4>
@endallowed

通过控制器操作名称

if (allowed([\App\Http\Controllers\HomeController::class, 'index'])) {
    echo "will allow here if the user has access";
}

// alternatively in blade template

@allowed([\App\Http\Controllers\HomeController::class, 'index'])
<h4>Will be visible if the user has permission</h4>
@endallowed

检查控制器级别访问

假设您有两个控制器名为 HomeControllerProfileController,现在您想检查用户是否对这两个控制器有任何访问权限,请使用以下代码

if (allowedAny(['Home','Profile'])) {
    echo "Will be visible if the user has permission for any action of Home and Profile controller";
}

// alternatively in blade template

@allowedAny(['Home','Profile'])
<h4>Will be visible if the user has permission for any action of Home and Profile controller</h4>
@endallowedAny

// for single controller it can be written like this

@allowedAny('Home')
<h4>Will be visible if the user has permission for any action of Home Controller</h4>
@endallowedAny

通过角色名称检查访问

if (hasRole(['Admin','Editor'])) {
    echo "Will be visible if the user has Admin or Editor or both roles";
}

// alternatively in blade template

@hasRole(['Admin','Editor'])
<h4>Will be visible if the user has Admin or Editor or both roles</h4>
@endhasRole

// for single Role it can be written like this

@hasRole('Admin')
<h4>Will be visible if the user has Admin roles</h4>
@endhasRole