Authentication CakePHP-将编辑限制在您自己的范围内”;“数据”;

Authentication CakePHP-将编辑限制在您自己的范围内”;“数据”;,authentication,cakephp,cakephp-1.3,access-control,Authentication,Cakephp,Cakephp 1.3,Access Control,目前,我使用Auth组件让用户登录/注销-ACL被定义为在用户组(来宾、用户、管理员)之间排序-具有明显的限制;管理员可以访问所有内容,用户只能访问用户控制器中的编辑,而来宾只能看到显示/索引/视图等 现在,为了防止用户编辑另一个用户,我有一个名为isOwner()的函数,它基本上检查您是否试图编辑自己的配置文件;并且还检查它是否是试图编辑的管理员。如果用户是他们试图编辑的内容的所有者,那么它允许编辑,否则它只会通过一条flash消息重定向 通读之后,我想知道是否可以在ACL中定义它 大致如下:

目前,我使用Auth组件让用户登录/注销-ACL被定义为在用户组(来宾、用户、管理员)之间排序-具有明显的限制;管理员可以访问所有内容,用户只能访问用户控制器中的编辑,而来宾只能看到显示/索引/视图等

现在,为了防止用户编辑另一个用户,我有一个名为isOwner()的函数,它基本上检查您是否试图编辑自己的配置文件;并且还检查它是否是试图编辑的管理员。如果用户是他们试图编辑的内容的所有者,那么它允许编辑,否则它只会通过一条flash消息重定向

通读之后,我想知道是否可以在ACL中定义它

大致如下:

$this->Acl->allow(array('model' => 'User', 'foreign_key' => $id), 'Users', 'edit', $id) 

虽然我还没有深入挖掘,我假设我必须对上面的行进行某种形式的beforeSave(),以允许每个注册的新用户编辑其个人资料。

[我决定将此作为一个答案发布,因为它包含代码示例]

您可以创建一个组件(或函数)并在app_控制器中使用beforeFilter()回调,这样您就不需要手动将函数添加到所有控制器中

此外,您还可以为操作使用多个前缀(请参阅核心中的
Routing.prefixes
),这将使控制访问变得更容易。比如:

[app\u controller.php]

function beforeFilter() {
    if(isset($this->params['prefix']) && $this->params['prefix'] == 'admin'){
         if(!isAdmin() || !isOwner())
             $this->cakeError('error404');
    }
}
  function admin_edit($id = null){
        ... // edit as usual
    }
[users\u controller.php]

function beforeFilter() {
    if(isset($this->params['prefix']) && $this->params['prefix'] == 'admin'){
         if(!isAdmin() || !isOwner())
             $this->cakeError('error404');
    }
}
  function admin_edit($id = null){
        ... // edit as usual
    }
在LAMP堆栈中,瓶颈通常位于数据库中

我对蛋糕的问题是它的查询数量。有一次,我看到我的“联系人”页面,该页面进行了21次查询,仅检索数据结构和此公共页面的权限

证明使用ACL访问数据的唯一方法是当权限是动态的时,即“用户29可以编辑用户12,因为管理员是在后台决定的”。但是,如果您有访问数据的静态规则(比如“用户只能编辑自己的信息,管理员可以编辑所有内容”),那么在您已经知道答案的情况下执行查询是没有用的,因为这些规则不会及时更改

所以这一切都取决于你的应用程序。。最后,最后一个想法是,如果您仍然计划进行更多查询=P,您可以。但在我看来,使用ACL组件来实现这一点似乎是个坏主意


干杯

好吧,差不多4年过去了,但对于像我这样的人来说,在研究CakePHP应用程序的Acl解决方案时偶然发现了这一点;简而言之,是的,这是可能的,但必须仔细计划。如果您真的需要这种级别的身份验证,那么Cake的ACL实现实际上没有可行的替代方案,这至少是合理的(不需要评论…)。注:当前稳定版本为2.4:

本质上,解决方案是用
$dbAcl->check($user,$entity,$action)替换您的
isOwner()
调用代码
它对ACL db结构进行查找-请参阅

当然,事情不止这些。CakePHP没有为您提供在实体级别进行此类身份验证的现成解决方案。它为您提供了一个工具包,您可以使用该工具包构建一个:

  • 用于查询ACL db结构的DbAcl
  • ACL的行为。要对其应用实体级授权的对象类的模型应加载Acl行为。这将自动创建和删除对象级别的ACO/ARO,并处理其中的所有内容。看
  • 控制器::isAuthorized()的控制器级授权。在这里您将调用
    dbAcl::check()
    。看见如果您真的需要,还可以从自定义授权模块执行此操作
  • 您仍然需要使用CRUD或操作授权组件来补充这一点。重要的是要认识到,在默认的CakePHP烘焙控制器中,有两个action/endpoint的隐式子类。作用于控制器本身(添加、索引)和作用于控制器所表示的对象类实体(编辑、查看、删除)的对象。这类似于类与实例方法。所描述的授权类型仅适用于作用于实体的端点。剩下的部分可以回退到操作/Crud auth
  • 您显然需要一个用户模型

注意,在ACL-上的Cake文档末尾有两个很好的教程。他们没有明确地介绍这种类型的设置,但是如果理解了所涉及的概念,再加上
dBAcl
,您应该能够按照自己的方式进行设置。

几乎是一样的事情不是真的-我实际上想使用ACO\u ARO来获得权限,而不是离开它。Cake的ACL使用起来很痛苦,不知道您为什么如此热衷于它。但是既然您使用了Auth,也许我可以建议您将$this->Auth->user()的内容设置为一个静态变量,然后您可以访问模型方法中的值。另外,我不会使用回调,因为它会使调试变得困难。我不同意这种说法——我认为ACL功能非常强大,并且可以在大型应用程序中轻松获得用户权限。我确实有$this->Auth->user()作为一个静态变量,在任何地方都可以访问,但它实际上与上面的问题无关?我发现回调很好——并不比ACL本身困难。嘿,沙兹,用户将如何访问另一个配置文件?用户/编辑操作不应采用id参数,它应始终假定发出请求的登录用户的id。我错过了什么吗?不同于我想要的,但仍然是一个很好的选择,谢谢!