【问题标题】:Zend Auth and ACLZend 身份验证和 ACL
【发布时间】:2009-01-22 12:02:23
【问题描述】:

我希望有些人可以帮助我一点,我目前正在使用 PHP 框架开发我的第一个网站,该网站的一部分被溢出到会员区,这是我的困惑开始浮出水面的地方,与会员区我希望普通成员能够添加新的 cmets 并在那里编辑自己的 cmets,足够简单,我可以根据存储在会话中的用户名检查海报名称,我的困惑来自于区分“普通”用户和能够删除和修改任何 cmets 等的高级用户,他们也应该能够访问站点的管理部分。

我的问题是所有用户都应该通过同一个 Zend_Auth 控制器登录,还是应该为每种类型的用户使用 Zend_Auth 的单独控制器,或者所有这些都可以使用 Zend_Acl 处理吗?任何帮助、建议、文章或教程将不胜感激。就我个人而言,我认为 Zend 文档在某些类上有点原始。

提前致谢

sico87

【问题讨论】:

    标签: php zend-framework authentication login


    【解决方案1】:

    我推荐 Manning Publications 的“Zend Framework in Action”一书作为对此的最新介绍。它可作为 PDF 下载,所以你现在可以拥有它:)

    但是要回答这个特定的问题:

    让我们从定义两个关键术语开始。 Zend_Auth 中的“Auth”指的是身份验证,它证明某人就是他们所说的人(即登录)。 Zend_Acl 中的“A”指的是授权,它证明某人有权做他们想做的事情(即访问控制)。

    假设用户只有一个角色... 将用户的角色存储在您作为 Zend_Auth 的一部分获得的“身份”中。 登录时:

    $auth = Zend_Auth::getInstance();
    $identity = new stdClass();
    $identity->user_pk = $user->getPrimaryKey();
    $identity->user_name = $user->getName();
    $identity->role = $user->getRole(); // select * from user_role where user_pk=xxx
    $auth->getStorage()->write($identity);
    

    在控制器中:

    $acl->add(new Zend_Acl_Resource('news'))
    ->allow('defaultRole', 'news');
    

    默认情况下所有内容都被拒绝,因此您实际上不需要指定:

    ->deny('defaultRole', 'news', 'add');
    

    在控制器的代码中进一步说明:

    $identity = Zend_Auth::getInstance()->getIdentity();
    if(!$acl->isAllowed($identity->role, 'news', 'add'))
    {
       header('Location: http://www.yoursite.com/error/unauthorized');
    }
    

    如果用户的身份不允许做“news->add”,它会将他们重定向到未经授权的页面(假设你已经做了这样的页面)。

    如果用户拥有 >1 个角色,您将在其身份中存储一组角色。 然后你的支票会是这样的:

    $identity = Zend_Auth::getInstance()->getIdentity();
    $isAllowed = false;
    foreach($identity->role as $role)
    {
       if($acl->isAllowed($role, 'news', 'add'))
       {
          $isAllowed = true;
       }
    }
    if(!$isAllowed)
    {  // if NO ROLES have access, redirect to unauthorized page
       header('Location: http://www.yoursite.com/error/unauthorized');
    }
    

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      是的,在大多数情况下,您的所有身份验证都应该通过同一个控制器。但是,Zend Auth 不是控制器类型。 Zend Auth 是一个 API,用于使用常见的身份验证方法,如数据库或 http。它的工作实际上只是对编写身份验证代码的繁重工作进行封装。

      Zend Acl 是您用来区分普通用户和特权用户的工具。只有在用户认证并登录后才涉及 Zend Acl。

      您需要的大部分内容都在 ZF 文档中。我阅读了几乎所有关于 Auth 和 Acl 的文档,然后才觉得它对我很有意义。尽管 ZF 的 Auth、ACL、Storage_* 和其他类非常紧密地一起使用,但它们的用途却截然不同。稍等片刻,您就会发现它们很好地建立在彼此的基础上。

      几个链接可以帮助您入门:

      Pádraic Brady's ZF Tutorial

      Zend's DevZone article on ACL and MVC

      【讨论】:

        【解决方案3】:

        我能理解你为什么会感到困惑。我/我还是有点困惑。所以,很遗憾,我无法直接回答您的问题。但是,为了澄清我脑海中的所有这些东西,我正在做的一件事是考虑“域对象”而不是数据库记录。

        我处理此问题的策略是创建我自己的身份验证适配器,该适配器与用户凭据一起传递“用户基础对象”。我的“用户群”有点像用户存储库。

        所以 Zend Auth 成为其他 Zend 组件的“接口”,而我仍然可以更好地控制我的系统以存储和访问“用户”。 我的 User_Base 类可以是 Zend Db tbl 的包装器,甚至可以在其中包含一些可用于测试的硬代码。

        一般来说-

        这就是我要做的。

        在我清楚 Auth 之前,我什至不会打扰 Zend ACL。


        我正在改造旧网站并将其转换为 Zend MVC

        为了让我的“模型”发挥作用,我必须掌握这些东西(也许是非常规的)。 :

        • 一个应用可能被来自多个“用户群”的用户使用 - openID、旧用户表、新用户表、转瞬即逝的客人等
        • 客人的身份可能只是他们第一次到达时创建的哈希
        • 而旧用户的身份可能由旧用户表中的 id 表示
        • users 和 user_accounts 是不同的东西。不要试图将它们混合成一个概念,因为它可能会变得复杂。
        • 系统中可能有许多不同类型的帐户。 IE。买家账户与卖家账户。 Readers_Account 与 Writers_Account
        • 帐户“拥有”用户 - “主要帐户持有人”、“管理员超级用户”等
        • 用户和帐户之间的关系由“account_users”(所有用户群中所有用户的本地子集)表示
        • 角色附加到 account_users(该特定帐户的用户)。(与浮动的角色相反)
        • 不要害怕在服务器上拥有多个 Zend 应用程序来代表一个网站 - 例如管理应用程序、会员应用程序、前端应用程序。
        • 不要害怕让这些应用使用存储在“共享模型”文件夹中的模型对象,只有与单个应用直接相关的模型代码位于 /application/models/foomodel 文件夹中。
        • 每个应用都可能有自己的自定义身份验证适配器
        • 管理员身份验证适配器可能只允许来自“管理员用户表”的用户,而前端应用的身份验证适配器可能能够对来宾用户群、员工或成员用户群的用户进行身份验证。
        • 可能是一种特殊情况,当会员登录时,前端应用会话被清除并由会员会话替换。
        • 每个网络客户端在任何时候每个应用一个用户对象(而不是尝试用来宾用户和成员用户引用一个人 - 这太复杂了)
        • 每个应用程序每个用户一个会话(命名空间以避免与他们可能在该域上登录的其他应用程序发生冲突) - (而不是尝试同时引用“使用它的人”与访客会话和成员会话。再次,这太复杂了)

        好的,我开始闲逛了....但你明白了。不要让您看到的 Zend_Auth+Zend Db 教程影响您自己的模型。它们只是简化的示例。

        nuff 说

        【讨论】:

          【解决方案4】:

          我对这段代码有几个问题

              $auth = Zend_Auth::getInstance();
              $identity = new stdClass();
              $identity->user_pk = $user->getPrimaryKey();
              $identity->user_name = $user->getName();
              $identity->role = $user->getRole(); // select * from user_role where user_pk=xxx
              $auth->getStorage()->write($identity);
          
              $identity = Zend_Auth::getInstance()->getIdentity();
          

          user_pk、user_name 和 role 是否存储为 cookie?制作具有角色名称的 cookie 的人是否能够访问网站的安全部分?密码(使用 md5 加密)不应该也是身份的一部分,以便何时可以验证每个请求的用户名和密码?

          【讨论】:

          • 为什么这个答案实际上是一个问题?
          猜你喜欢
          • 1970-01-01
          • 2016-05-10
          • 1970-01-01
          • 1970-01-01
          • 2011-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多