spekkionu/laravel-zend-acl

通过Laminas\Permissions\Acl组件将ACL添加到Laravel中。

v8.0.0 2023-04-03 23:05 UTC

README

Latest Stable Version Total Downloads Build Status Scrutinizer Quality Score SensioLabsInsight Code Coverage

通过Laminas\Permissions\Acl组件将ACL添加到Laravel 5或Lumen中。

大多数Laravel的ACL解决方案将权限规则存储在数据库或其他持久层中。如果访问是动态的,这很好,但对于通过角色设置权限的应用程序,这使得修改更困难。添加新资源、权限或角色需要通过迁移或其他方式运行数据库查询。使用此包,权限存储在代码中,因此存储在版本控制中(希望如此)。

而不是重新发明轮子,此包利用了Zend Framework的ACL包。Laminas\Permissions\Acl的文档可以在https://docs.laminas.dev/laminas-permissions-acl/找到。

安装

从项目根目录运行composer require spekkionu/laravel-zend-acl

设置

Laravel

  1. 对于低于5.5版本的Laravel,将'Spekkionu\ZendAcl\ZendAclServiceProvider',添加到config/app.php中的服务提供者列表。对于5.5及以上的Laravel,此步骤不是必需的。
  2. 'Acl' => 'Spekkionu\ZendAcl\Facades\Acl',添加到config/app.php中的别名列表。
  3. 运行php artisan vendor:publish --provider="Spekkionu\ZendAcl\ZendAclServiceProvider"

发布后,权限将在routes/acl.php中定义。

Lumen

  1. $app->register(Spekkionu\ZendAcl\ZendAclLumenServiceProvider::class);添加到bootstrap/app.php中的Register Service Providers部分。
  2. vendor/spekkionu/laravel-zend-acl/src/config/zendacl.php文件复制到应用根目录的config文件夹中(如果不存在,则创建文件夹)。
  3. vendor/spekkionu/laravel-zend-acl/src/config/acl.php文件复制到routes文件夹中(此文件夹还应包含web.php路由文件)。

从版本6迁移

Zend框架库的命名空间已从Zend更改为Laminas。

要将迁移到7.x分支,您需要将项目中所有对旧Zend命名空间的引用更改为新Laminas命名空间。

这可能会包括将用户模型实现的RoleInterface从Zend\Permissions\Acl\Role\RoleInterface更改为Laminas\Permissions\Acl\Role\RoleInterface

还要在所有对Zend\Permissions\Acl\Acl的类型提示处更改为Laminas\Permissions\Acl\Acl

使用

Laminas\Permissions\Acl可以通过Facade Acl或通过IOC容器中的acl服务访问。IOC容器还可以通过类型提示Laminas\Permissions\Acl\Acl来注入acl实例。

可以在app/Http/acl.php中修改权限。

添加资源

您可以使用addResource方法添加新的资源。

<?php
// Add using string shortcut
$acl->addResource('page');
// Add using instance of the Resource class
$acl->addResource(new \Laminas\Permissions\Acl\Resource\GenericResource('someResource'));
?>

添加角色

您可以使用addRole方法添加新的角色。

<?php
// Add using string shortcut
$acl->addRole('admin');
// Add using instance of the Role class
$acl->addRole(new \Laminas\Permissions\Acl\Role\GenericRole('member'));
?>

添加/删除权限

您可以使用allow方法添加权限。

<?php
// Add page resource
$acl->addResource('page');
// Add admin role
$acl->addRole('admin');
// Add guest role
$acl->addRole('guest');
// Give admin role add, edit, delete, and view permissions for page resource
$acl->allow('admin', 'page', array('add', 'edit', 'delete', 'view'));
// Give guest role only view permissions for page resource
$acl->allow('guest', 'page', 'view');
?>

您可以使用deny方法删除权限。

<?php
// Add page resource
$acl->addResource('page');
// Add admin role
$acl->addRole('admin');
// Give admin role add, edit, delete, and view permissions for page resource
$acl->allow('admin', 'page', array('add', 'edit', 'delete', 'view'));
// Add staff role that inheirits from admin
$acl->addRole('staff', 'admin');
// Deny access for staff role the delete permission on the page resource
$acl->deny('staff', 'page', 'delete');
?>

检查权限

您可以使用isAllowed方法检查访问权限

给定以下权限

<?php
// Add page resource
Acl::addResource('page');
// Add admin role
Acl::addRole('admin');
// Add guest role
Acl::addRole('guest');
// Give admin role add, edit, delete, and view permissions for page resource
Acl::allow('admin', 'page', array('add', 'edit', 'delete', 'view'));
// Give guest role only view permissions for page resource
Acl::allow('guest', 'page', 'view');
?>
<?php
// Check if admin can add page
// Should return true
$allowed = Acl::isAllowed('admin', 'page', 'add');

// Check if admin can delete page
// Should return true
$allowed = Acl::isAllowed('admin', 'page', 'delete');

// Check if guest can edit page
// Should return false
$allowed = Acl::isAllowed('guest', 'page', 'edit');

// Check if guest can view page
// Should return true
$allowed = Acl::isAllowed('guest', 'page', 'view');
?>

检查用户的权限

为了检查登录用户的权限,用户需要有一个字段来存储用户的角色。如果使用Eloquent用户模型,让用户模型实现Laminas\Permissions\Acl\Role\RoleInterface。该接口有一个方法getRoleId(),应返回用户的角色。

示例模型

假设有一个名为 users 的表,该表有一个字段 role。下面的模型将允许将用户模型的实例传递给 isAllowed() 方法。

<?php
use Illuminate\Database\Eloquent\Model;
use Laminas\Permissions\Acl\Role\RoleInterface;

class User extends Model implements RoleInterface
{
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * Returns role of the user
     * @return string
     */
    public function getRoleId()
    {
        return $this->role;
    }
}

使用用户模型检查权限

<?php

// Checking if a user has permissions to view an article
$user = User::find(1);
Acl::isAllowed($user, 'article', 'view');

// Checking if the currently logged in user has permissions to edit a blog post
Acl::isAllowed(Auth::user(), 'post', 'edit');

将权限检查添加到路由

此包中包含一个 acl 路由中间件,允许您通过路由限制访问。路由中间件需要 Auth::user() 返回的模型实现上述 Laminas\Permissions\Acl\Role\RoleInterface

注册 acl 中间件

Laravel

将以下内容添加到 app/Http/Kernel.php 中的 $routeMiddleware 数组。

'acl' => \Spekkionu\ZendAcl\AclMiddleware::class,
Lumen

将以下内容添加到 bootstrap/app.php$app->routeMiddleware() 方法中的数组。

'acl' => \Spekkionu\ZendAcl\AclMiddleware::class,

使用 acl 中间件

您可以将中间件添加到任何路由中,作为前置中间件,如下所示。

Route::get('article/{id}', ['middleware' => ['acl:article,view'], 'uses' => 'ArticleController@show']);

当请求路由时,它将检查当前登录用户是否有对文章资源的查看权限。如果没有登录用户(Auth::guest() 返回 true),则将检查 guest 角色。

如果用户可以访问指定的资源,则将正常调用控制器。

如果用户没有权限访问资源时的操作可以在 config/zendacl.php 中进行配置。

如果用户未授权,可以采取两种不同的操作。

  1. 可以将用户重定向到 URL 或命名路由。这可以通过将 action 设置为 "redirect" 或 "route" 并将 redirect 设置为 URL 或命名路由来实现。

  2. 可以渲染一个视图。这可以通过将 action 设置为 "view" 来实现。view 设置控制要渲染的视图。默认情况下,视图将位于 resources/vendor/zendacl/unauthorized。此视图可以进行修改,或将 view 设置更改为其他视图。

Ajax 请求将发送 401 响应,无论设置如何。