2

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

例如,我有以下两个模型:

Assignments
Users

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

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

我已经知道我可以通过将组条件放入查找中然后在代码中适当的查看/编辑/删除操作来做到这一点。

我的问题是 - 在 cakephp 中处理此类场景的最佳方法是什么?到处设置条件对我来说似乎不是好方法。

4

2 回答 2

3

考虑作为两个单独的问题来解决

访问控制

第一个是如何拒绝学生,例如,只是操纵 url 来尝试查看/编辑/删除他们不拥有的东西。对于这种使用isAuthorized,书中有一个示例,适用于问题中的信息:

// 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 起可用的事件系统是实施上述数据限制的简单方法。书中再次有一个相关示例,适用于问题中的信息,即:

// 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所有查找添加一个条件,因此索引列表将仅显示他们自己的作业,而对于教师,它将显示所有作业。

于 2013-07-24T21:48:34.563 回答
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');以提取单个用户的所有分配

于 2013-07-24T20:45:52.530 回答