sitepoint /rauth
一个基于注解的基本访问控制列表(ACL)包
Requires
- php: ~7.0
Requires (Dev)
- phpunit/phpunit: ~5
- scrutinizer/ocular: ~1.1
- squizlabs/php_codesniffer: ~2.3
- symfony/var-dumper: ~3
This package is not auto-updated.
Last update: 2024-09-12 00:14:13 UTC
README
Rauth 是一个简单的包,用于解析 docblock 中的 @auth-*
行。然后,它们与一些任意属性(如“分组”、“权限”等)进行匹配。以下为基本用法示例。
为什么?
我想
- 能够定义“规则”,而无需将我的路由绑定到大量正则表达式上
- 能够随心所欲地更改路由,并使规则适用于整个应用、API 模式或 DOM 模式,而无需进行任何更改。通过将权限放在类和方法上,我可以更好地控制应用设置和其角色。
注解很糟糕™
“有些争议性地”,Rauth 默认使用注解来控制访问。无论你属于 PHP 中注解的哪一阵营,以下原因说明在 Rauth 的情况下使用注解远没有某些人所说的那么糟糕
-
因为通常在典型的 MVC 应用中,你会控制对控制器和操作的访问,将它们与 Rauth 这样紧密耦合不仅无害(如果你正在更改框架或以重大方式更改应用结构,控制器几乎总是需要完全丢弃和重写),而且还能让你立即了解到哪个类/方法有哪些 ACL 要求
-
如果你不喜欢注解,可以向 Rauth 提供一个预先缓存的或预先解析的权限和它们应用的类的列表,这样就可以完全避免注解问题
-
不再担心注解会减慢速度,因为 PHP 需要反射到相关的类中,并在每次都需要提取它们。如果始终开启 OpCache,则这只会发生一次,而使用 Rauth 自带的缓存支持,甚至可以将这些信息保存到其他地方,从而避免注解读取过程。
安装
通过 Composer
composer require sitepoint/rauth
基本用法
在某个地方(最好是引导文件,或者你配置 DI 容器的任何位置)引导 Rauth,如下所示
<?php $rauth = new Rauth();
注意:您还可以使用 setCache
或 Rauth 构造函数注入一个 Cache 对象。默认为 ArrayCache(因此,效率低下且实际上不缓存任何内容),但可以替换为任何遵循 Cache 接口的任何内容。请参阅 src/Rauth/Cache.php
。
在类或方法的 docblock 的 @auth-*
行中定义 要求
<?php namespace Paranoia; /** * Class MyProtectedClass * @package Paranoia * * @auth-groups admin, reg-user * @auth-permissions post-write, post-read * @auth-mode OR * */ class MyProtectedClass {
“分组”和“权限”是用户可以拥有的任意 属性 - 如果你愿意,可以使用“香蕉”或“松鼠吊床”。重要的是,你需要用逗号分隔它们的值,并且标签以 @auth-
开头。
检查用户是否有权访问给定的类/方法
try { $allowed = $rauth->authorize($classInstanceOrName, $methodName, $attributes); } catch (\SitePoint\Rauth\Exception\AuthException $e) { $e->getType(); // will be "ban", "and", "or", etc... $e->getReasons(); // an array of Reason objects with details }
$attributes
将是一个数组,这完全取决于你实现用户属性的方式。也许你正在使用 Gatekeeper 并可以直接访问 User
实体上的 groups
和/或 permissions
,也许你有一个完全定制的系统。重要的是,你需要构建一个包含以下属性的数组
$attributes = [ 'groups' => ['admin'] ];
或者可能是这样的
$attributes = [ 'permissions' => ['post-write', 'post-read'] ];
或者甚至可能是这样的
$attributes = [ 'groups' => ['admin', 'reg-user'], 'permissions' => ['post-write', 'post-read'] ];
你明白了。
请记住:
@auth-*
行是要求,它们将与属性进行比较。
Rauth将解析@auth
行,并将所需的属性以类似方式保存到数组中。
$requirements = [ 'mode' => RAUTH::OR, 'groups' => ['admin', 'reg-user'], 'permissions' => ['post-write', 'post-read'] ];
authorize
如果在一切顺利的情况下将返回true
。
如果authorize
检查失败,它将抛出AuthException
。该AuthException
将有一个getType
getter,它将返回失败发生的模式字符串值——无论是ban
、and
、or
、none
还是完全自定义的模式(见下面的模式)。它还将有一个getReasons
getter,它提供了一个包含Reason
对象的数组。每个对象都有以下公共属性:
group
:定义哪个@auth-{group}
触发了异常,例如“groups”、“permissions”、“banana”或其他任何内容。has
:该组提供的属性数组。如果没有提供任何属性,则为空数组。needs
:需要的/禁止的属性数组,并与has
进行比较。
可用模式
这些模式可以用作@auth-mode
的值。
或
模式OR
将使Rauth::authorize()
在**任何**属性与**任何**要求匹配时返回true
。
和
模式AND
将使Rauth::authorize()
在**所有**属性与**所有**要求匹配时返回true
(例如,用户必须拥有文档块中提到的所有组、所有权限和所有香蕉)。
无
模式NONE
将仅在没有任何属性与要求匹配时使Rauth::authorize()
返回true
。
禁止
您还可以使用@auth-ban
标签。
/* * ... * @auth-ban-groups guest, blocked * ... */
如果找到匹配项,此标签将具有优先权。因此,在上面的示例中——如果用户是管理员,但也是blocked
组的成员,他们将无法访问。无论其他所有匹配项如何,只要用户的所有匹配项都为零,他们就可以继续进行。
禁止锤具有绝对权威,不会对
@auth-mode
做出反应。在检查其他权限之前,必须完全清除所有禁止。
缓存
Rauth在其构造函数中接受一个需要遵守src/Rauth/Cache.php
接口的Cache对象。它默认为ArrayCache,这是一个假的缓存,实际上并没有大幅提高速度,主要用于开发期间。
请注意,您可以将一个现成的数组传递给ArrayCache(构造函数接受数据),如果您有的话。这样,您将为Rauth填充缓存,它就不必手动解析它尝试授权的每个类。
$ac = new ArrayCache( [ 'SomeClass' => [ 'mode' => RAUTH::OR, 'groups' => ['admin', 'reg-user'], 'permissions' => ['post-write', 'post-read'], ], 'SomeClass::someMethod' => [ 'mode' => RAUTH::AND, 'groups' => ['admin'], ], ] ); $rauth = new Rauth($ac);
最佳实践
为了不手动使用authorize
调用,最好将其与依赖注入容器或路由分配器相关联。这样,您可以轻松地将要求放入控制器的文档块中,并在启动时构建属性,其余的将自动完成。有关此示例,请参阅nofw框架。
@todo 此示例将很快添加
测试
composer test
贡献
请参阅CONTRIBUTING。
致谢
许可
MIT许可(MIT)。请参阅许可文件以获取更多信息。