2011-04-29 26 views
3

我正在研究'私人'應用程序,您必須登錄後才能執行任何操作。這給我一個加載Zend Navigation角色的問題。目前,我正在啓動Zend Navigation,這很好,直到我將ACL添加到Zend Nav。問題是,我想從我的auth存儲中加載'userRole',但是直到用戶登錄纔會有存儲,所以在登錄頁面中給我一個'嘗試獲取非對象屬性'警告。這是因爲在登錄之前,auth的存儲中沒有任何內容,所以auth->userRole是'沒有',因爲auth->getInstance()->getIdentity()->???將是空的,直到用戶登錄並且配置了auth。Zend導航:我應該在哪裏加載私人應用程序中的ACL'角色'

我沒有在登錄頁面使用Zend Nav,實際上我有一個替代的登錄頁面佈局(根本沒有導航); 'if !$auth->hasIdentity'(false)使用登錄佈局,僅在系統範圍內顯示該問題的登錄頁面,正如我所說的,應用程序是完全私人的,因此默認爲「客人」角色或類似的東西似乎是一種「髒」的方法,因爲一旦用戶登錄,它將不得不重新配置auth。爲了取悅登錄頁面而設置通用身份驗證標識似乎不太合適。

我得到的是,移動Zend Nav'init'的好地方,還是至少移動configure ACL部分?也可以移動整個事情?

這是我在我的bootstrap.php中的Zend的導航:

protected function _initNavigation() { 
    $this->_logger->info('Bootstrap ' . __METHOD__); 

    $this->bootstrap('layout'); 
    $layout = $this->getResource('layout'); 
    $view = $layout->getView(); 
    $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav'); 
    $container = new Zend_Navigation($config); 
    $acl = new Application_Model_Acl_Acl(); 
    $role = Zend_Auth::getInstance()->getIdentity()->userRole; 
    $view->navigation($container)->setAcl($acl)->setRole($role); 
} 

這在當時是引導運行的'$role = Zend_Auth::getInstance()->getIdentity()->userRole'是空的(或非對象)。

我所有的ACL都發生在控制器中(在動作中),或者某些時候可能發生在模型中,雖然我不會指責Web服務或任何東西,所以他們可能會留在控制器中,但我有靈活性,因爲我有在模型中的ACL(這將是'域'的權利?

我只在Zend Nav上使用ACL用於佈局,用戶體驗目的;菜單和鏈接根據用戶角色,Zend Nav將是'灰色',不存在或活動(和可見),例如'用戶'角色不會獲得許多'管理員'選項,並且這在ACL中由ACL重新實施控制器,所以不能簡單地輸入網址並獲得一個區域。

我的另一個想法是,也許我應該考慮將這種情況下的登錄名移動到引導程序中,但我不確定這是一個好主意嗎?


編輯: 這是我投入的前端控制器插件代碼:

class Plugins_Controller_ZendNavInit extends Zend_Controller_Plugin_Abstract { 

     public function preDispatch(Zend_Controller_Request_Abstract $request) { 

      $auth = Zend_Auth::getInstance(); 

      if ($auth->hasIdentity()) { 

       $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav'); 
       $container = new Zend_Navigation($config); 
       $acl = new Application_Model_Acl_Acl(); 

       $layout = Zend_Layout::getMvcInstance(); 
       $view = $layout->getView(); 

       $role = Zend_Auth::getInstance()->getIdentity()->userRole; 
       $view->navigation($container)->setAcl($acl)->setRole($role); 
      } 
     } 
    } 

偉大工程;當然,我必須像任何其他註冊我的插件。我也將我的Auth檢查移到了前端控制器插件上。

回答

3

您可以在登錄之前構建一個匿名角色,併爲匿名用戶處理非常短的ACL策略。 檢查this response舉例說明如何使用Auth插件捕獲PreDispatch上的不確定用戶。

+0

感謝您的回答。我會在今天下午看到它並回來。它使'默認用戶'的想法聽起來不那麼'髒':) – rhaag71 2011-04-29 16:22:09

+0

我認爲這(你所建議的)是我將要去的解決方案,創建一種'登錄頁面'的僞角色並對待它就像它的'登錄頁面'角色一樣,在用戶登錄時會被註銷;基本上只是'cearIdentity()',然後將新的認證寫入存儲。感謝您的鏈接並花時間給出答案。 – rhaag71 2011-05-01 05:10:46

+0

對於將來的旁觀者,我在我的原始任務(上面)中編輯了我在新的Front Controller Plugin中使用的代碼。 – rhaag71 2011-05-07 20:04:13

1

我不會直接從Auth存儲中獲取它。如果您從Zend_Auth中提取它,並在該用戶會話期間更改了用戶角色,則您必須強制註銷/登錄或更新Zend_Auth存儲中的信息。我發現設置一個Role類並執行邏輯來確定其中的角色或設置默認(guest)角色會更容易。用戶角色類擴展了我的用戶模型並實現了Zend_Acl_Role_Interface。然後我可以從Role類中查詢數據庫。我開始實施這一天左右前,但這裏有一個例子:

<?php 

類Zfcms_Acl_Role_User擴展Zfcms_Model_Users實現Zend_Acl_Role_Interface的 {

/** 
* Unique id of Role 
* 
* @var string 
*/ 
protected $_roleId; 
public $_inheritsFrom = 'guest'; 
public $_defaultRole = 'user'; 

/** 
* Sets the Role identifier 
* 
* @param string $id 
* @return void 
* Defined by Zend_Acl_Role_Interface; returns the Role identifier 
* 
* @return string 
*/ 
public function getRoleId() 
{ 
    //$auth = Zend_Auth::getInstance(); 
    if(Zend_Auth::getInstance()->hasIdentity()) 
    { 
     $this->_roleId = self::getUserRoleById(Zend_Auth::getInstance()->getIdentity()->user_id); 
     return $this->_roleId; 
    } 
    elseif(!Zend_Auth::getInstance()->hasIdentity() && !isset($this->role)) 
    { 
     //return 'guest'; 
     return (string) new Zfcms_Acl_Role_Guest(); 
    } else { 
     throw new Zend_Controller_Action_Exception('Invalid user roleId', 110); 
    } 
} 
public function getDefaultRole() 
{ 
    return $this->_defaultRole; 
} 
public function getPrivsByRole($role) 
{ 
    //TODO: Design db table to hold privs 
} 
private function setPrivs() 
{ 
    //TODO: implement 
} 
/** 
* Defined by Zend_Acl_Role_Interface; returns the Role identifier 
* Proxies to getRoleId() 
* 
* @return string 
*/ 
public function __toString() 
{ 
    return $this->getRoleId(); 
} 
public function getUserRoleById($id) 
{ 
    $this->_id = $id; 
    $query = $this->select() 
        ->from('users', array('user_id', 'role')) 
        ->where('user_id = ?', $this->_id); 

    $result = $this->fetchAll($query); 
    foreach($result as $userRole) 
    { 
     $role = $userRole->role; 
    } 
    return $role; 
} 

}

+0

感謝您發佈您的方法。我將仔細研究一下這個問題,結果我對當時正在進行的項目做得很好,但由於你陳述的原因,我擔心未來的項目(在我的腦海中) (註銷/英寸)。 – rhaag71 2011-07-29 17:21:30

相關問題