1

我想Zend\Permissions\Acl不仅(仅)基于静态角色而且还基于(可变)用户点来使用 Zend 的 ACL ( )。

在我的应用程序中,每个用户都有积分。资源具有查看它所需的最少点数。对资源的访问应基于用户当前拥有的点数。

例子

资源:

  • 资源 1:20 分
  • 资源 2:100 分
  • 资源 3:150 分

用户:

  • 用户 1:70 分 => 访问资源 1
  • 用户 2:135 分 => 访问资源 1、2
  • 用户 3:170 分 => 访问资源 1、2、3

最好的方法是什么?

到目前为止我的想法

  1. 根据当前登录的用户的点数动态创建 ACL 对象($acl->allow()根据点数设置每个用户)。这不干净。
  2. 创建一个通用 ACL 并以某种方式传递用户的观点(我设法通过断言来做到这一点。请参阅下面的答案。)
  3. 这里建议了一些(可能更简单/更清洁)的方式......

我将不胜感激朝着正确的方向前进:)

4

2 回答 2

2

因此,这不仅与 Zend 有关,而且与一般的 ACL 一起使用。

通常,当您在 ACL 中实现访问权限时,您会将其分配给一个组而不是单个用户。然后,您可以轻松(并且动态地)在组中添加或删除用户。

在 Zend ACL 中,您可以将这些组视为角色。在您的情况下,您将资源的访问权限分配给代表一定数量点的组(或角色)。现在您只需要担心根据他们获得的积分在这些组之间移动用户。

于 2013-05-28T18:55:39.273 回答
1

好的,我尝试自己实现它。也许它不漂亮,但这是我自己想出的最佳解决方案。这是正确的方向吗?我将不胜感激任何反馈!

解决方案:

我使用我的模型而不是字符串作为资源和角色(这里建议)。我PointResourceInterface用来标记需要特定点数的资源并Zend\Permissions\Acl\Role\RoleInterface在我的用户类中实现。现在我创建一个新的NeededPointsAssertion

class NeededPointsAssertion implements AssertionInterface
{
    public function assert(Acl $acl, RoleInterface $role = null, 
            ResourceInterface $resource = null, $privilege = null) {
        // Resource must have points, otherwise not applicable
        if (!($resource instanceof PointResourceInterface)) {
            throw new Exception('Resource is not an PointResourceInterface. NeededPointsAssertion is not applicable.');
        }

        //check if points are high enough, in my app only users have points
        $hasEnoughPoints = false;
        if ($role instanceof User) {
            // role is User and resource is PointResourceInterface
            $hasEnoughPoints = ($role->getPoints() >= $resource->getPoints());
        }

        return $hasEnoughPoints;
    }
}

PointResourceInterface看起来像这样:

use Zend\Permissions\Acl\Resource\ResourceInterface;

interface PointResourceInterface extends ResourceInterface {
    public function getPoints();
}

设置:

$acl->allow('user', $pointResource, null, new NeededPointsAssertion());

用户可以访问需要积分的资源。但另外NeededPointsAssertion检查。

访问: 我正在检查是否允许这样访问:

$acl->isAllowed($role, $someResource);

如果有用户$role = $user,否则它是guest或其他东西。

灵感来自http://www.aviblock.com/blog/2009/03/19/acl-in-zend-framework/

更新:现在回过头来看,也可以通过构造函数添加所需的点并将其存储为属性。自己决定什么在你的应用程序中有意义......

于 2013-05-29T09:23:49.303 回答