我正在处理'私人'应用程序,您必须登录才能执行任何操作。这给我一个加载Zend Navigation角色的问题。目前我在我的引导程序中'初始化'Zend Navigation;在我向Zend Nav添加ACL之前一切正常。问题是我想从我的auth存储加载'userRole',但是在用户登录之前还没有存储,所以这会让我在登录页面看到'试图获取非对象的属性'警告。这是因为在登录之前,auth的存储中没有任何内容,因此auth->userRole
是'无',因为auth->getInstance()->getIdentity()->???
将为空,直到用户登录并配置了auth。
我没有在登录页面上使用Zend Nav,事实上我有一个登录页面的替代布局(根本没有导航); 'if !$auth->hasIdentity'
(false)使用登录布局,只显示系统范围内的登录页面,因为我说应用程序是完全私有的,所以默认为“访客”角色或类似的东西看起来像'脏'方法,因为一旦用户登录,无论如何都必须重新配置auth。为了取悦登录页面,设置通用身份验证身份似乎是不对的。
我得到的是,移动Zend Nav的'init'或者至少移动配置ACL部分的好地方在哪里?还可以移动整个事情吗?
这就是我在我的bootstrap.php中为Zend Navigation提供的内容:
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在控制器中重新强制执行,因此无法简单地键入url并进入某个区域。
我的另一个想法是,也许我应该考虑将我的登录信息转移到这种情况的引导程序中,但我不确定这是一个好主意吗?
修改 这是我放入Front Controller插件的代码:
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检查移动到前端控制器插件。
答案 0 :(得分:3)
您可以在登录前构建匿名角色,并为匿名用户处理非常短的ACL策略。 请查看this response,了解如何使用Auth插件捕获PreDispatch上未经验证的用户。
答案 1 :(得分:1)
我不会直接从Auth存储中提取它。如果从Zend_Auth中提取它,并且在该用户会话期间用户的角色已更改,则您必须强制注销/登录或更新Zend_Auth存储中的信息。我发现设置Role类并执行逻辑以确定其中的角色或设置默认(guest)角色更容易。 User角色类扩展了我的User模型并实现了Zend_Acl_Role_Interface。然后,我可以从Role类中查询db。我大约一天前开始实现这个,但这是一个例子:
<?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;
}
}