CakePHP - 限制编辑您自己的“数据”

发布于 2024-11-25 09:29:36 字数 663 浏览 1 评论 0 原文

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

现在为了防止用户编辑另一个用户 - 我有一个名为 isOwner( )这主要检查您是否正在尝试编辑自己的个人资料;并检查是否是管理员尝试编辑。如果用户是他们尝试编辑的内容的所有者,则它会允许编辑,否则它只会使用闪现消息进行重定向。

阅读http://book.cakephp.org/ view/1245/Defining-Permissions-Cake-s-Database-ACL - 我想知道是否可以在 ACL 中定义它?

大致如下:

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

虽然我还没有深入挖掘,并且我假设我必须使用上述行为每个注册的新用户创建某种 beforeSave() 才能编辑他的个人资料。

At the moment I use Auth Component for users to login / logout - ACL is defined to sort between user groups (Guests, Users, Admins) - with obvious restrictions; Admin being able to access everything, the user can only access edit in the users controller and the guest being able to see just the display / index / view etc etc.

Now to prevent users from editing another user - I have a function called isOwner() which essentially checks if you are trying to edit your own profile; and also checks if it is an admin trying to edit. If the user is the owner of the content they're trying to edit, then it allows it otherwise it just redirects with a flash message.

Having read through http://book.cakephp.org/view/1245/Defining-Permissions-Cake-s-Database-ACL - I wondered if it was possible to define this in the ACL?

Something along the lines of:

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

Though I haven't dug deep enough and I'm assuming I'd have to make some sort of beforeSave() with the above line for each new user registered to be allowed to edit his profile.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你怎么这么可爱啊 2024-12-02 09:29:36

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

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

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

[app_controller.php]

function beforeFilter() {
    if(isset($this->params['prefix']) && $this->params['prefix'] == 'admin'){
         if(!isAdmin() || !isOwner())
             $this->cakeError('error404');
    }
}

[user_controller.php]

  function admin_edit($id = null){
        ... // edit as usual
    }

在 LAMP 堆栈中,您的瓶颈通常位于数据库

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

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

所以这一切都取决于你的应用程序..最后,最后一个想法,如果你仍然计划进行更多查询=P你可以设置Auth组件的授权方法。但为此使用 ACL 组件在我看来是个坏主意

干杯!

[ i've decided to post this as an answer cause it contains code examples ]

You could create a component (or a function) and use the beforeFilter() callback in the app_controller, that way you wont need to manually add the function to all controllers.

Also you could use multiple prefixes for the actions (see Routing.prefixes in the core), it will make it easier to control the access. Something like:

[app_controller.php]

function beforeFilter() {
    if(isset($this->params['prefix']) && $this->params['prefix'] == 'admin'){
         if(!isAdmin() || !isOwner())
             $this->cakeError('error404');
    }
}

[users_controller.php]

  function admin_edit($id = null){
        ... // edit as usual
    }

In a LAMP stack your bottleneck is usually at the database

my problem with cake is the number of queries it makes. Once i saw that my "contact" page that made 21 queries only to retrieve the data structure, and the permissions for this public page.

The only way to justify the use of ACL for accessing data is when the permissions are dynamic, i.e. "user#29 can edit user#12 because the Admin decided it in the backoffice". But if you have static rules for accessing the data (like "users can only edit their own info and admins can edit everything") its kinda useless to perform queries when you already know the answers, because this rules won't change in time.

so it all depends on your app.. Finally, one last thought, if you're still planing to make more queries =P you could set the authorize method of the Auth component. But using the ACL Component for this, seems to me like a bad idea

Cheers!

花伊自在美 2024-12-02 09:29:36

好吧,差不多 4 年后了,但对于像我这样的人来说,研究 CakePHP 应用程序的 Acl 解决方案时偶然发现了这一点;简短的回答是,这是可能的,但必须仔细计划。如果您确实需要这种级别的身份验证,那么除了 Cake 的 ACL 实现之外,并没有真正可行的替代方案,这至少是合理的(不进行批评......)。请注意,当前稳定版本是 2.4:

本质上,解决方案是将代码中的 isOwner() 调用替换为 $dbAcl->check($user, $entity, $action) ; 对 ACL 数据库结构进行查找 - 请参阅 http://api.cakephp.org/2.4/class-DbAcl.html

当然,还有更多的事情要做。 CakePHP 没有为您在实体级别提供这种类型的身份验证的开箱即用的解决方案。它为您提供了一个工具包,您可以使用它来构建一个工具包:

  • 用于查询 ACL 数据库结构的 DbAcl。
  • Acl 行为。您想要应用实体级授权的对象类的模型应该加载 Acl 行为。这会自动创建和删除对象级 ACO/ARO,处理其中的所有内容。请参阅http://api.cakephp.org/2.4/class-AclBehavior.html
  • 使用 Controller::isAuthorized() 进行控制器级别授权。您将在此处调用 dbAcl::check()。请参阅http://book.cakephp.org/2.0/ en/core-libraries/components/authentication.html#authorization。如果您确实愿意,也可以通过自定义授权模块来完成此操作。
  • 仍然需要使用 CRUD 或 Action Authorize 组件来补充这一点。重要的是要认识到,在默认的 CakePHP 烘焙控制器中,有 2 个操作/端点的隐式子类。那些作用于控制器本身的(添加、索引)以及作用于控制器所表示的对象类的实体的那些(编辑、查看、删除)。这类似于类方法与实例方法。所描述的授权类型仅适用于作用于实体的端点。剩下的事情你可以回退到 Action/Crud auth。
  • 显然,您需要一个用户模型。

请注意,Cake 文档末尾有两个关于 ACL 的很好的教程 - http://book.cakephp.org/2.0/en/tutorials-and-examples。他们没有明确地涵盖这种类型的设置,但只要了解所涵盖的概念以及 dBAcl,您应该能够按照自己的方式进行设置。

Ok it's almost 4 years later but for those who like me stumble across this researching an Acl solution for a CakePHP app; The short answer is yes it is possible, but it has to be planned carefully. If you really need this level of Auth there is not really a viable alternative to Cake's ACL implementation, which is at the least sound (not going into a critique...). Note current stable version is 2.4:

In essence, the solution is to replace your isOwner() call in your code with $dbAcl->check($user, $entity, $action); which does a lookup on your ACL db structure - see http://api.cakephp.org/2.4/class-DbAcl.html.

There is more to it than that of course. CakePHP does not provide you with an out of the box solution for this type of authentication at the entity level. It provides you a toolkit that you can use to build one:

  • The DbAcl for querying the ACL db structure.
  • The AclBehavior. The models of the classes of objects that you want to apply entity level authorization on should load the Acl behavior. This automatically creates and deletes object level ACO/AROs, taking care of everything there. See http://api.cakephp.org/2.4/class-AclBehavior.html.
  • Controller level authorization with Controller::isAuthorized(). This is where you'll call dbAcl::check(). See http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#authorization. You could also do it from a custom Authorize module if you really wanted.
  • You still need to complement this by using either CRUD or Action Authorize component. Its important to realize that in a default CakePHP baked controller there are 2 implicit subclasses of action/endpoint. Those that act on the Controller itself (add,index) and those that act on an entity of the class of objects represented by the controller (edit,view,delete). This is analogous to class vs instance methods. The type of authorization described is only applicable to the end point that acts on an entity. You fallback to Action/Crud auth for the rest.
  • You'll obviously need a User model..

Note there is two good tutorials at the end of the Cake docs on ACL - http://book.cakephp.org/2.0/en/tutorials-and-examples. They don't cover this type of setup explicitly but given an understanding of the concepts covered plus dBAcl you should be able to make you own way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文