CakePHP 2.x ACL - 在所有者级别进行控制

时间:2015-10-15 06:45:20

标签: php cakephp acl

我可以使用ACL控制我的应用程序,一切都做得很完美,应用程序与ACLAuth一起顺利进行。

现在的问题是:

我有两个表,usersposts。没有RBAC(基于角色的访问控制)。 我为每个用户设置了denyallow,例如关注。

//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才能在这里工作,有可能吗?请帮助

由于

1 个答案:

答案 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'));

我没有测试上面的代码,所以我猜也有很多错别字和错误。如果我有时间,我会在接下来的几天里做一些测试并改进我的答案