Cakephp 的acl問題

edited 十月 2013 in CakePHP
研究了cakephp 官網的acl 一段時間,也實做成功
但發現官網的教學, 尚缺一項功能.


就是扮演user的這個role,不能設定為僅修改自己的文章,
後來發現一篇教學,內容是寫一個function 來檢查該user是不是文章的發佈者.

http://aranworld.com/article/189/cakephp-acl-and-auth-record-level-protection-and-crud
function checkUsersOwnRecord($recordId = null)
 { if( $this->Auth->user('id') == $recordId )
{ return TRUE; }
 else { return FALSE; } }

我根據了這個藍本.稍微的修改了一下.
雖然還有些bug,但也確實實現了 , 只有發布者才能修改自己的文章這個功能.
function edit($id = null) {
 if (!$id && empty($this->data)) 
        { $this->Session->setFlash(__('Invalid Post', true)); 
         $this->redirect(array('action'=>'index')); } 
 if (!empty($this->data))
    { $edit_permit=$this->data['Post']['user_id']; //use user_id to disguish the user only can edit      his own article 
 //and other user role don't hav the permission to edit , 
echo "______".$edit_permit."_______"; //just want to make sure , we are in the way of edit this post 

     if($this->checkUser($edit_permit)==TRUE){
 //add if ($this->Post->save($this->data))

 { $this->Session->setFlash(__('The Post has been saved',$edit_permit, true)); 
//orginal $this->redirect(array('action'=>'index'));
 } else { $this->Session->setFlash(__('The Post could not be saved. Please, try again.', true)); } } else 
{ $this->redirect(array('action'=>'index')); 
$this->Session->setFlash(__('The Post could not be saved. Please, try again.', true)); }
 } if (empty($this->data))
{ $this->data = $this->Post->read(null, $id); }
 $users = $this->Post->User->find('list');
 $this->set(compact('users')); }


不過相同的程式碼帶入view 的這個function, 卻發現了問題 ,希望有人能為我解惑, 感謝
function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Post.', true)); $this->redirect(array('action'=>'index')); } else{ $edit_permit=13; //use user_id to disguish the user only can edit his own article echo "--->".$edit_permit."<---"; if($this->checkUser($edit_permit)==TRUE){ $this->set('post', $this->Post->read(null, $id)); } else {$this->redirect(array('action'=>'index'));} } }









原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=4924

評論

  • edited 二月 2010
    = = 排版上好像有些困難 , 我再貼一次好了,

    我根據了這個藍本.稍微的修改了一下. 雖然還有些bug,但也確實實現了 , 只有發布者才能修改自己的文章這個功能.

    function edit($id = null) {





    if (!$id && empty($this->data)) {
    $this->Session->setFlash(__('Invalid Post', true));
    $this->redirect(array('action'=>'index'));
    }


    if (!empty($this->data)) {

    $edit_permit=$this->data; //use user_id to disguish the user only can edit his own article
    //and other user role don't hav the permission to edit ,
    echo "______".$edit_permit."_______";
    //just want to make sure , we are in the way of edit this post

    if($this->checkUser($edit_permit)==TRUE){
    if ($this->Post->save($this->data)) {
    $this->Session->setFlash(__('The Post has been saved',$edit_permit, true));
    //orginal $this->redirect(array('action'=>'index'));


    } else {
    $this->Session->setFlash(__('The Post could not be saved. Please, try again.', true));

    }


    }
    else {

    $this->redirect(array('action'=>'index'));
    $this->Session->setFlash(__('The Post could not be saved. Please, try again.', true));
    }
    }


    if (empty($this->data)) {
    $this->data = $this->Post->read(null, $id);
    }
    $users = $this->Post->User->find('list');
    $this->set(compact('users'));
    }



  • edited 二月 2010
    不過相同的程式碼帶入view 的這個function, 卻發現了問題 ,希望有人能為我解惑, 感謝

    function view($id = null) {





    if (!$id) {
    $this->Session->setFlash(__('Invalid Post.', true));
    $this->redirect(array('action'=>'index'));
    }

    else{

    $edit_permit=13; //use user_id to disguish the user only can edit his own article
    //這裡的$edit_permit用13 是因為我目前的user_id是13, 我嘗試用$this->data;卻顯示空白,
    echo "--->".$edit_permit."<---";

    if($this->checkUser($edit_permit)==TRUE){


    $this->set('post', $this->Post->read(null, $id));
    }
    else
    {$this->redirect(array('action'=>'index'));}
    }



    }




    另外checkUser Function如下,

    function checkUser($recordId=null){

    if($this->Auth->user('id') == $recordId){return TRUE;}
    else {return FALSE;}

    }
  • edited 二月 2010
    在 checkUser() 中把相關資料印出來看看
    pr($this->Auth->user('id'))
    

    你就知道哪裡出問題了
  • edited 二月 2010
    似乎edit , 會印出user的id ,
    而view, 則是顯示空白 ,

    我猜是不是要post資料過去 edit, 才會顯示 , 因為view 是沒資料post過來的.
  • edited 二月 2010
    不確定,不過我都是自己在 Session 撈,放在 AppController 的 beforeFilter() ,像這樣:
    $this->loginUser = $this->Session->read('Auth.User');
            if(empty($this->loginUser)) {
                $this->loginUser = array(
                    'id' => 0,
                    'group_id' => 0,
                    'username' => '',
                );
            }
    

    然後在每個 Controller 透過 $this->loginUser 確認使用者身份
  • edited 二月 2010
    原來是這樣...感謝你的解答 Q_Q
    我試看看~
  • edited 二月 2010
    最近我又找到了一篇關于cakephp acl的文章,這個方法似乎跟官網的一個小節有點關連

    //Remember, we can use the model/foreign key syntax
    //for our user AROs $this->Acl->check(array('model' => 'User', 'foreign_key' => 2356), 'Weapons');

    來源:http://book.cakephp.org/view/471/Checking-Permissions-The-ACL-Component

    當初我也覺得這個小節似乎可以對檢查個人用戶的權限起些作用. 不過只有短短1行, 不知道實際應該怎麼做.


    後來這位大大似乎提出了比較具體的方法 ,

    The final touches will come as you update or create your model actions. WHen a user creates a new Toolbox (for example) you will immediately grant that user update and delete privileges for that toolbox.

    //example code when a user creates a model
    //let user with id 1234 update toolbox with id 5678
    $this->Acl->allow(array('model' => 'User', 'foreign_key' => 1234), array('model'=>'Toolbox','foreign_key'=>'5678'), 'update');
    Next time around you can use ACL to verify those rights to prevent anyone else the same privilege.

    //example code when a user attempts action a model
    //can user with id 1234 in fact update toolbox with id 5678?
    $this->Acl->check(array('model' => 'User', 'foreign_key' => 1234), array('model'=>'Toolbox','foreign_key'=>'5678'), 'update');

    來源: http://edwardawebb.com/programming/php-programming/cakephp/started-acl-cakephp



  • edited 二月 2010
    透過 ACL 方式實作其實是相對複雜,如果只是單純的作者辨識,透過簡單的程式碼判斷即可,但如果涉及複雜的授權關係,也許可以考慮 ACL ,但是會需要比較長的時間進行開發。
  • edited 二月 2010
    因為最近想實驗性的做個社群網站 , 想說應該需要這方面的知識.

    另外 , 我看了某位大大詳盡的教學 , 已經解決了這個問題. (雖然看了2天 , 還有些想不通的地方, 不過確實這個教學是我目前看過最完整的 , 如果有人也想要實作看看, 建議從PART1 開始)


    //PRODUCT的ADD


    function add() {
    if (!empty($this->data)) {
    $this->Product->create();
    if ($this->Product->save($this->data)) {
    $dealer = $this->Product->Dealer->read(null,
    $this->data);
    $parent = $this->Acl->Aco->findByAlias(
    $dealer);
    $alias = $this->Product->id.'-'.$this->data
    ;
    $aco = new Aco();
    $aco->create();
    $aco->save(array(
    'alias' => $alias,
    'model' => 'Product',
    'foreign_key' => $this->Product->id,
    'parent_id' => $parent
    ));
    $this->Acl->allow('Users', $alias, 'read');
    $this->Acl->allow($this->Session->read('user'), $alias);
    $this->Session->setFlash(__('The Product has been saved', true));
    $this->redirect(array('action'=>'index'));
    } else {
    $this->Session->setFlash(__('The Product could not be saved.
    Please, try again.', true));
    }
    }
    $dealers = $this->Product->Dealer->find('list');
    $this->set(compact('dealers'));
    }





    //這個是PRODUCT的VIEW

    function view($id = null) {
    if (!$id) {
    $this->Session->setFlash('Invalid Product.', true));
    $this->redirect(array('action'=>'index'));
    }
    $product = $this->Product->read(null, $id);
    $alias = $id . '-' . $product;
    if ($this->Acl->check($this->Session->read('user'), $alias;
    $id . '-' . $product, 'read')) {
    $this->set('product', $product);
    } else {
    $this->Session->setFlash('Only registered users may view this product.');
    $this->redirect(array('action'=>'index'));
    }
    }





    我貼一下link, 如果以後有人遇到相同的問題 , 也可以作為參考

    原文
    http://www.ibm.com/developerworks/opensource/tutorials/os-php-cake2/section8.html
    中譯版:
    https://www.ibm.com/developerworks/cn/opensource/tutorials/os-php-cake2/



  • edited 二月 2010
    Register相當與Users的Add


    function register()
    {
    if (!empty($this->data))
    {
    $this->data = md5($this->data
    );
    if ($this->User->save($this->data))
    {
    $this->Session->setFlash('Your registration information
    was accepted');
    $this->Session->write('user', $this->data);
    $parent = $this->Acl->Aro->findByAlias('Users');
    $aro = new Aro();
    $aro->create();
    $aro->save(array(
    'alias' => $this->data,
    'model' => 'User',
    'foreign_key' => $this->User->id,
    'parent_id' => $parent)
    );
    $this->Acl->Aro->save();
    $this->redirect(array('action' => 'index'), null, true);
    } else {
    $this->data = '';
    $this->Session->setFlash('There was a problem saving
    this information');
    }
    }
    }
  • edited 三月 2010
    後來才發現 , 原來這篇教學也在官網的教學列表中....
    = = 鬼打牆 , 一直沒看到他
Sign In or Register to comment.