sitepoint/rauth

一个基于注解的基本访问控制列表(ACL)包

0.1 2016-02-20 19:34 UTC

This package is not auto-updated.

Last update: 2024-09-12 00:14:13 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score

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将有一个getTypegetter,它将返回失败发生的模式字符串值——无论是banandornone还是完全自定义的模式(见下面的模式)。它还将有一个getReasonsgetter,它提供了一个包含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)。请参阅许可文件以获取更多信息。