在cakephp中记录级访问权限

时间:2013-07-24 09:37:57

标签: php cakephp permissions

我想根据登录用户查看记录来限制记录。

例如,我有两个模型:

Assignments
Users

因此,如果学生(用户)正在查看作业摘要,他应该只能看到他的作业,并且只能查看/删除/编辑他的作业。

但是如果教师(用户)正在查看作业摘要,那么他应该看到所有作业,并且可以对所有作业执行添加/编辑/删除。

我已经知道我可以通过将组条件放入find中,然后在视图/编辑/删除操作中的代码中使用。

我的问题是 - 在cakephp中处理这样的场景的最佳方法是什么?在任何地方设置条件对我来说似乎都不是好方法。

2 个答案:

答案 0 :(得分:3)

考虑解决两个独立的问题

访问控制

首先是如何否认学生,例如只需操纵网址即可查看/编辑/删除他们不拥有的内容。对于那个使用是授权的,有an example in the book,适用于问题中的信息:

// app/Controller/AppController.php

public $components = array(
    'Session',
    'Auth' => array(
        'authorize' => array('Controller') // Added this line
    )
);

public function isAuthorized($user) {
    // Teachers can access/do everything - adapt to whatever identifies a teacher
    if ($user['is_teacher'])) {
        return true;
    }

    // Anyone logged in can access the index
    if ($this->action === 'index') { 
        return true;
    } 

    // The owner of a whatever can view, edit and delete it
    $id = $this->request->params['pass'][0];
    $owner = $this->{$this->modelClass}->field('user_id', array('id' => $id));
    if ($owner === $user['id'])) {
        return true;
    }

    // Default deny
    return false;
}

限制学生数据

自2.1起可用的

The event system是一种简单的方法来强制执行上述数据限制。再次there's a relevant example in the book,适应问题中的信息,即:

// app/Controller/AssignmentsController.php

public function beforeFilter() {
    if (!$this->Auth->user('is_teacher')) {
        $currentUser = $this->Auth->user('id');
        $this->Assignment->getEventManager()->attach(
            function(CakeEvent $e) use ($currentUser) {
                $e->data[0]['conditions']['user_id'] = $currentUser;
                return $e->data[0];
            },
            'Model.beforeFind'
        );
    }
}

这将为所有查找添加user_id条件,因此索引列表将仅显示自己的分配,而对于教师,它将显示所有分配。

答案 1 :(得分:1)

我会创建2个独立的模型 - StudentAssignments和TeacherAssignments。两种模型都可以扩展Assignments模型。然后,您可以在每个模型的beforeFind中过滤条件。 这样,您就可以解耦模型,并且可以适当地操作它们。

示例:

App::uses('Assignment', 'Model');

class StudentAssignments extends Assignment
{
    function beforeFind( $queryData ) {
        $queryData['conditions'] = array_merge( (array)$queryData['conditions'], 
                                    array( $this->alias.'.user_id' => CakeSession::read('User.id') ) );
        return parent::beforeFind($queryData);
    }

}

然后,您可以致电$this->StudentAssignments->find('all');以提取单个用户的所有作业