spekkionu / laravel-zend-acl
通过Laminas\Permissions\Acl组件将ACL添加到Laravel中。
Requires
- php: >=8.0
- illuminate/support: 6.* | 7.* | 8.* | 9.* | 10.*
- laminas/laminas-permissions-acl: ^2.14
Requires (Dev)
- mockery/mockery: ~1.0
- phpunit/phpunit: ^8.0
README
通过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
- 对于低于5.5版本的Laravel,将
'Spekkionu\ZendAcl\ZendAclServiceProvider',
添加到config/app.php
中的服务提供者列表。对于5.5及以上的Laravel,此步骤不是必需的。 - 将
'Acl' => 'Spekkionu\ZendAcl\Facades\Acl',
添加到config/app.php
中的别名列表。 - 运行
php artisan vendor:publish --provider="Spekkionu\ZendAcl\ZendAclServiceProvider"
发布后,权限将在routes/acl.php
中定义。
Lumen
- 将
$app->register(Spekkionu\ZendAcl\ZendAclLumenServiceProvider::class);
添加到bootstrap/app.php
中的Register Service Providers
部分。 - 将
vendor/spekkionu/laravel-zend-acl/src/config/zendacl.php
文件复制到应用根目录的config
文件夹中(如果不存在,则创建文件夹)。 - 将
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
中进行配置。
如果用户未授权,可以采取两种不同的操作。
-
可以将用户重定向到 URL 或命名路由。这可以通过将
action
设置为 "redirect" 或 "route" 并将redirect
设置为 URL 或命名路由来实现。 -
可以渲染一个视图。这可以通过将
action
设置为 "view" 来实现。view
设置控制要渲染的视图。默认情况下,视图将位于resources/vendor/zendacl/unauthorized
。此视图可以进行修改,或将view
设置更改为其他视图。
Ajax 请求将发送 401 响应,无论设置如何。