我可以使用ACL
控制我的应用程序,一切都做得很完美,应用程序与ACL
和Auth
一起顺利进行。
现在的问题是:
我有两个表,users
和posts
。没有RBAC
(基于角色的访问控制)。
我为每个用户设置了deny
和allow
,例如关注。
//allow User1 to do everything
$user->id=1;
$this->ACL->allow($user,'controllers');
//allow User2 to add, edit and view the posts
$user->id=2;
$this->Acl->deny($user, 'controllers');
$this->Acl->allow($user, 'controllers/Posts');
但在这里我遇到了一个问题:
user2
可以访问edit
posts
user1
。
示例:
User1
创建了post1
。
现在User2
已登录,他可以修改User1
的帖子(即post1- /localhost/myApp/posts/edit/1
)
问题:如何为此问题设置ACL权限,帖子的所有者只能编辑帖子,而其他人则不能。
我可以在控制器级别实现这一点,只需检查
if($_SESSION['Auth']['User']['id'] == $Post['Post']['user_id']){
// you're the owner, so u can edit
}else{
//u cant edit, this is not ur post
}
但我需要ACL
才能在这里工作,有可能吗?请帮助
由于
答案 0 :(得分:4)
这是我将如何做的
首先告诉Cake,Post
模型是ACO
// Post.php model file
$actsAs = array('Acl' => array('type' => 'controlled'));
这样每次创建新的post cake都会自动在acos
表中创建一个项目。
注意:您必须以这种方式为以前创建的帖子手动创建节点:
// for every Post in your posts table
$this->Acl->Aco->create(array('alias' => 'Post', 'id' => 123));
$this->Acl->Aco->save();
然后你必须在你的帖子模型文件中定义一个parentNode()
函数
// Post.php model file
public function parentNode() {
return null;
}
现在ACL auth处理程序仅在操作级别检查表单权限。换句话说,它只是检查您是否被允许访问该操作。然后它需要isAuthorized()
函数在控制器级别进行其他检查。
所以首先你必须为每个节点设置权限
$this->Acl->allow($user, 'controllers/Posts/edit/123')
然后在你的控制器中你必须做
// PostsController.php
public function isAuthorized($user = null) {
if ($this->request->action === 'edit') {
$user = // retrieve the user array. i.e. from Session
$post_id = $this->request->$this->request->pass[0];
$post = array('alias' => 'Post', 'id' => $post_id );
return this->Acl->check($user, $post);
}
return parent::isAuthorized($user);
}
你也可以实现parentNode()函数来返回Post的所有者而不是null
// Post.php model file
// just an hint, the actual code should be
// a bit more complex
public function parentNode() {
$user_id = $this->field('user_id');
return array('User' => array('id' => $user_id));
}
这种方式不必为每个帖子设置权限,因为cake会检查用户是否有权访问Post的父节点(谁也是用户)。所以你只需要为每个用户设置权限
$this->Acl->allow($user, $user);
如果您遵循此方法,请记住将用户设置为ACO
// User.php Model file
$actsAs = array('Acl' => array('type' => 'both'));
我没有测试上面的代码,所以我猜也有很多错别字和错误。如果我有时间,我会在接下来的几天里做一些测试并改进我的答案