How to limit data to users who own it without limiting admin users in CakePHP?

后端 未结 3 957
太阳男子
太阳男子 2020-12-18 09:17

Currently I am writing an application where I have multiple users. They have data that should only be visible to them and not the other authenticated users in the system. I

相关标签:
3条回答
  • 2020-12-18 09:36

    For any one else who comes here this is how I set it up.

    First I set up a basic Role based ACL

    Then I deny access to reports/all for normal users

    $config['rules']['deny'][reports/all'] = 'Role/default' ;
    

    Then in the model that I wanted to protect I added this:

    public function beforeFind($queryData){
        //TODO:make this cleaner
        App::uses('ComponentCollection', 'Controller');
        App::uses('AclComponent', 'Controller/Component');
        $collection = new ComponentCollection();
        $this->Acl = new AclComponent($collection);     
    
        if(!$this->Acl->check(array('User'=>AuthComponent::user()),'/reports/all/')){  // must be a user (not admin)
            $this->bindModel(array('hasOne' => array('ReportsUser')));
            $queryData['conditions']['ReportsUser.user_id'] = AuthComponent::user('id');
            $queryData['recursive'] = 2;
        }
        return $queryData;
    }
    

    On the cases where ACL doesn't allow access to reports/all we add a condition to any find queries so it only shows reports with the correct user_id.

    0 讨论(0)
  • 2020-12-18 09:47

    You can get the current user info this way: $this->Auth->user(). You can use the user group id in your callback to limit the query. Also take a loot at WhoDidIt Behavior.

    0 讨论(0)
  • 2020-12-18 09:55

    You need:

    • Information about the current user
    • Information about the item in question

    You combine them with something like this (simple example):

    $user = $this->Auth->user();
    $book = $this->Book->find(…);
    if ($user['type'] != 'admin' && $user['id'] != $book['Book']['creator_id']) {
        $this->Session->setFlash("You're not allowed to view this item");
        $this->redirect('somewhere');
    }
    

    You could make a method in your model like

    function userCanAccessItem($item, $user)
    

    to centralize the logic for the access check and call it from your controller.

    Better yet, if you're using Cake's admin routing, you can omit all checking in the admin_ actions and only apply normal user access privilege checking in the user accessible actions.

    You may also want to look at ACLs for more fine-grained access control.

    0 讨论(0)
提交回复
热议问题