应该在哪里进行Acl过滤?

时间:2011-05-24 21:34:34

标签: php zend-framework zend-acl

假设我有三个表:usersbooksusers_books

在我的一个观点中,我想显示当前用户有权访问的所有图书的列表。如果users_books中存在与用户和图书匹配的行,则用户可以访问图书。

我至少有两种方法可以做到这一点:

  • fetchAll()模型的books方法中,在join表格上执行某种users_books
  • 在Acl插件中,首先从每本书中创建一个资源。然后,从每个用户创建一个角色。接下来,根据users_books表允许或拒绝用户访问每个资源。最后,在fetchAll()模型的books方法中,使用当前用户作为角色,在我们找到的每本书上调用isAllowed()

我认为最后一个选项是最好的,因为我可以在我的应用程序的其他地方使用Acl。这将消除执行重复访问检查的需要。

你会建议什么?

2 个答案:

答案 0 :(得分:1)

我会把它全部推到数据库中:

  1. 通过JOIN在数据库中执行此操作比在PHP中过滤内容要快得多。
  2. 在数据库中执行此操作可以让您正确地对事物进行分页,而不必像获取更多数据那样跳过箍(如果最终投入太多,则会获取更多数据)。
  3. 我可以想到您可以采用两种广泛的策略来管理ACL。

    您可以在数据库中设置显式ACL,其中包含以下表格:

    • id:有问题的东西(书,图片......)。
    • id_type:id来自的类型或表。
    • user:可以查看该内容的用户。

    idid_type)对为您提供伪FK,您可以使用它来对数据库进行健全性检查,id_type可以用来选择一个类来提供必要的粘合剂,用于交互ACL的类型特定部分,并将SQL片段添加到查询中以正确加入ACL表。

    或者,您可以使用命名约定将ACL边车表附加到每个表而不需要ACL。对于表格t,您可以使用包含以下列的表t_acl

    • idt中的东西的id(带有真正的外键,用于完整性)。
    • user:可以查看该内容的用户。

    然后,您可以拥有一个可以根据基表名称调整SQL的ACL类。

    第一种方法的主要优点是您可以为所有内容提供单个ACL存储,因此很容易回答诸如“用户X可以查看什么?”之类的问题。第二种方法的主要优点是你可以拥有真正的参照完整性和更少的代码(通过命名约定)来粘合它们。

    希望以上内容有助于您的思考。

答案 1 :(得分:1)

我会通过在存储库类中创建一个finder方法,使用getBooksByUser(User $ user)等添加方法来返回图书对象的集合,从模型中分离出数据库访问代码。

不完全确定您需要来自您描述的ACL。我可能错了。