【问题标题】:Zend_Auth identity versioningZend_Auth 身份版本控制
【发布时间】:2011-07-14 01:03:28
【问题描述】:

有一种情况:我将一些结构化数据(例如数组或对象,甚至字符串)存储为 Zend_Auth 身份。从一个版本到另一个版本,身份的结构可以改变,因此一个版本的身份可以(或不能)与另一个版本的应用程序代码兼容。

我希望能够验证存储的身份数据是否符合当前版本要求。

我从手册中看到,身份是否存在的验证是这样执行的:

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // Identity exists; get it
    $identity = $auth->getIdentity();
}

但是无法挂钩到hasIdentity() 方法或其他地方来执行验证。

我认为这样做的唯一方法是实现我自己的 Zend_Auth_Storage_Interface 类,该类将使用其他一些存储作为实现并执行存储数据的验证。

有没有更合适的解决方案?

【问题讨论】:

    标签: php zend-framework versioning zend-auth


    【解决方案1】:

    我不确定是否完全理解,但您似乎误解了授权和身份验证之间的区别。

    Zend_Auth 是关于身份验证的,因此您应该使用 Zend_Auth 来处理授权,而是使用 Zend_Acl。

    但是,如果您想要存储来自身份验证过程(即数据库身份验证)的附加信息,您可以使用getResultRowObject($returnColumns, $ommitColumns); 方法。

    根据您当前的适配器,有几种实现来获取“行对象”。

    Zend_Auth_Storage_Interface 是关于存储结果的,我认为你不需要做这样的实现,因为它是关于将身份对象存储在会话或数据库中。

    您可能想要的是使用 Zend_Acl 并构造一个访问控制列表,该列表通常定义一个角色可以是用户)、一个资源您的版本化应用程序),权限可以使用或不使用


    注意: *大多数人使用 Zend_Acl 有困难,因为他们在 Module/Controller/Action 中思考,但这只是定义资源的一种方式。
    资源可以是任何你想要的,整个应用程序、控制器操作、视图、另一个用户、数据库连接等。*

    【讨论】:

    • 你说得对。我使用 Zend_Auth 来验证用户并使用 Zend_Acl 来授权他或她(过滤导航和 preDispatch 上的权限验证)。但是我怎么能通过 Zend_Acl 确定身份是错误的呢?这是否意味着用户没有任何权限或类似的东西?
    • 更具体地说:该网站仅由会员区组成。这意味着当用户未登录时,必须显示登录表单而不是任何页面。否则,当用户登录时,他应该看到他被允许访问的网站部分。所以可能在身份错误的情况下,我必须将用户的角色确定为“匿名”,而不是将其作为匿名处理。
    • 您是对的,因为角色的工作方式,您可以将它们从不太宽松的角色继承到最强大的角色。我通常使用访客作为我的起始角色,具有访问登录页面和登录的唯一权限,然后我提升权限。
    【解决方案2】:

    即使你接受了上面的答案,我相信你还需要别的东西。

    $auth = Zend_Auth::getInstance();
    if ($auth->hasIdentity()) {
        // Identity exists - validate if it's valid
    
        $identity = $auth->getIdentity();
        if (!HelperClass::validateIdentity($identity)) { //you validation method
             /* User has stored identity from previous version. 
              * It may miss some important info (like a role value
              * you added recently). Clear it and require re-login. */
             $auth->clearIdentity();
             $this->_helper->flashMessenger('Please login ...');
             $this->_helper->redirector('login');
        }
        // identity is valid
        $acl = Acl::factory(); //get acl object somehow
        if (!$acl->isAllowed($module.$controller.$action, $identity->role)) {
             throw new AccessDeniedException();
        }
        // else nothing -> user has valid session data and is allowed to access the resource. 
    }
    

    【讨论】:

    • 没错,但我希望“当前用户是否登录”的逻辑被封装在某个地方。它将允许在多个地方重用该逻辑而不会丢失某些东西。 Acl 似乎正是那个地方。在您的示例中,对 hasIdentity() 的验证及其验证分布在两个不同的类(代码段)之间,这使得逻辑的凝聚力降低。
    • AcL 不适合该 IMO。 ACL 接收登录用户并决定用户是否可以/不能访问某些资源。它不应该决定用户是否登录...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2020-04-06
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多