Zend Navigation:我应该在哪里加载 ACL“角色”?在私人应用程序中
我正在开发一个“私人”应用程序,您必须登录才能执行任何操作。这给我加载 Zend Navigation 的角色带来了一些问题。目前我正在我的引导程序中“初始化”Zend Navigation;在我将 ACL 添加到 Zend Nav 之前,一切都很好。问题是我想从我的身份验证存储加载“userRole”,但在用户登录之前不会有存储,因此在登录页面上会出现“尝试获取非对象的属性”警告。这是因为在登录之前,auth 的存储中没有任何内容,因此 auth->userRole 为“无”,因为 auth->getInstance()->getIdentity()-> ???
将为空,直到用户登录并配置身份验证。
我没有在登录页面使用 Zend Nav,事实上我有一个登录页面的替代布局(根本没有导航); 'if !$auth->hasIdentity'
(false) 使用登录布局,仅在系统范围内显示登录页面,正如我所说,该应用程序是完全私有的,因此默认为 '来宾角色或类似的角色似乎是一种“肮脏”的方法,因为一旦用户登录,无论如何都必须重新配置身份验证。只是为了取悦登录页面而设置通用身份验证身份似乎并不正确。
我的意思是,哪里是移动 Zend Nav 的“init”或至少移动配置 ACL 部分的好地方?还可以把整个东西搬走吗?
这就是我在 Zend Navigation 的 bootstrap.php 中的内容:
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 重新强制执行的,因此不能简单地键入 我的另一个想法是,
也许我应该考虑将我的登录移动到引导程序中,但我也不确定这是一个好主意
编辑: 这是我放入前端控制器插件中的代码:
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);
}
}
}
效果很好;当然,我必须像其他插件一样注册我的插件。我还将身份验证检查移至前端控制器插件。
I am working on a 'private' application, you must be logged in to do anything at all. This gives me a bit of a an issue loading the role for Zend Navigation. Currently I am 'init'ing Zend Navigation in my bootstrap; that was fine until I added ACL to Zend Nav. The issue is that I want to load the 'userRole' from my auth storage, but there will not be storage yet until the user logs in, so that gets me a 'Trying to get property of non-object' warning at the login page. This is because before login, there is nothing in auth's storage, so auth->userRole
is 'nothing' because auth->getInstance()->getIdentity()->???
would be empty, until a user logs in and the auth is configured.
I'm not using Zend Nav at the login page, in fact I have an alternate layout for the login page (no nav at all); 'if !$auth->hasIdentity'
(false) use the login layout, only show the login page for that matter system-wide, as I said the application is completely private so defaulting to a 'guest' role or something like that seems like a 'dirty' approach, because once a user logs in it will have to reconfigure auth anyhow. It just don't seem right to set a generic auth identity just to please the login page.
What I am getting at is, where is a good place to move the 'init' of Zend Nav, or at least move the configure ACL part? May as well move the whole thing?
This is what I have in my bootstrap.php for 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);
}
It is the '$role = Zend_Auth::getInstance()->getIdentity()->userRole'
that is empty (or a non-object) at the time bootstrap runs.
All of my ACL takes place either in the controller (at the action) or some may take place in the models at some point, although I don't anticicpate web service or anything, so maybe they will stay in the controller, but I have the flexibility because I have the ACL in the models (that would be the 'domain' right?
I am only using ACL on Zend Nav for layout, user experience purposes; The menu and links I get from Zend Nav will be 'greyed', non-existant, or active (and visible) according to the user role, for example a 'user' role will not get many 'admin' options, and this is re-enforced by ACL in the controller so one could not simply type the url and get to an area either.
My other thought was that maybe I should be thinking of moving my login into the bootstrap for this situation, but I'm not sure that is a good idea either?
EDIT:
This is the code that I put into a Front Controller Plugin:
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);
}
}
}
Works great; I of course, had to register my plugin just like any other. I also moved my Auth checking to a front-controller plugin too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以在登录前建立一个匿名角色,并为匿名用户处理非常短的 ACL 策略。
查看此响应了解如何捕获未经身份验证的示例使用 Auth 插件使用 PreDispatch 的用户。
You could build an anonymous role before login and handle a very short ACL policy for anonymous users.
Check this response for example on how to catch unauthentified users on PreDispatch with an Auth Plugin.
我不会直接从 Auth 存储中提取它。如果您从 Zend_Auth 中提取它,并且在该用户会话期间用户的角色发生更改,您将必须强制注销/登录或更新 Zend_Auth 存储中的信息。我发现设置角色类并执行逻辑以确定那里的角色或设置默认(来宾)角色更容易。 User 角色类扩展了我的 User 模型并实现了 Zend_Acl_Role_Interface。然后我可以从 Role 类中查询数据库。我大约一天前开始实现这个,但这里有一个例子:
class Zfcms_Acl_Role_User extends Zfcms_Model_Users Implements Zend_Acl_Role_Interface
{
}
I would not pull it directly from the Auth storage. If you pull it from Zend_Auth and during that users session the user's role is changed, you will either have to force a logout/login or update the info in the Zend_Auth storage. I find it easier to setup a Role class and perform the logic to determine the role there or set a default (guest) role. The User role class extends my User model and implements Zend_Acl_Role_Interface. I can then query the db from within the Role class. I started implementing this a day or so ago but here is an example:
class Zfcms_Acl_Role_User extends Zfcms_Model_Users implements Zend_Acl_Role_Interface
{
}