我想使用Zend的ACL(Zend\Permissions\Acl
)不是(仅)基于静态角色,而是基于(变量)用户点。
在我的应用程序中,每个用户都有积分。资源具有查看它所需的最少点数。对资源的访问应基于用户当前拥有的点数。
示例
资源:
用户:
最好的方法是什么?
到目前为止我的想法
$acl->allow()
)。这不干净。我非常感谢推动正确的方向:)
答案 0 :(得分:2)
所以这不仅仅是关于Zend,而是一般使用ACL。
通常,当您在ACL中实施访问权限时,您将其分配给组而不是单个用户。然后,您可以轻松(并动态)添加或删除组中的用户。
在Zend ACL中,您可以将这些组视为角色。在您的情况下,您将资源的访问权限分配给表示一定数量的点的组(或角色)。现在,您只需担心根据他们获得的积分在这些群组之间移动用户。
答案 1 :(得分:1)
好的,我试着自己实现它。也许它不漂亮,但这是我自己提出的最好的解决方案。这是正确的方向吗?我将不胜感激任何反馈!
解决方案:
我使用我的模型(suggested here)而不是字符串作为资源和角色。我使用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/
更新:现在回过头来看,也可以通过构造函数添加所需的点并将其存储为属性。决定你自己以及你的应用程序有什么意义......