5

我正在使用使用 Zend 框架的Social Engine为网站开发一个模块。我是 Zend Framework 和 Social Engine 的新手,但在 OOP 和 MVC 架构方面有经验,因此可以相对较快地掌握基础知识。

它是我正在开发的一个测试模块,所以刚刚构建了一个简单的模块,用户可以在其中创建、编辑或删除 CD 信息。然后有一个小部件可以显示在他们喜欢的地方,其中显示了 CD 信息。

我现在需要设置人们可以看到的 CD 的权限等。所以我研究了其他模块,发现 Poll 模块就是一个具体的例子。

查看其他模块,我意识到当您创建某些内容时,它们会让用户手动设置权限。

所以将此代码添加到我的表单中以创建具有相关权限的选择框:

$auth = Engine_Api::_()->authorization()->context;
$user = Engine_Api::_()->user()->getViewer();
$viewOptions = (array) Engine_Api::_()->authorization()->getAdapter('levels')->getAllowed('ryan', $user, 'auth_view');
$viewOptions = array_intersect_key($availableLabels, array_flip($viewOptions));

$privacy = null;

if( !empty($viewOptions) && count($viewOptions) >= 1 ) {
    // Make a hidden field
    if(count($viewOptions) == 1) {
        //$this->addElement('hidden', 'auth_view', array('value' => key($viewOptions)));
        $privacy  = new Zend_Form_Element_Hidden('auth_view');
        $privacy->setValue(key($viewOptions));
        // Make select box
    } else {
        $privacy = new Zend_Form_Element_Select('auth_view');
        $privacy->setLabel('Privacy')
                ->setDescription('Who may see this CD?')
                ->setMultiOptions($viewOptions)
                ->setValue(key($viewOptions));
        /*$this->addElement('Select', 'auth_view', array(
            'label' => 'Privacy',
            'description' => 'Who may see this CD?',
            'multiOptions' => $viewOptions,
            'value' => key($viewOptions),
        ));*/
    }
}

$this->addElements(array($artist, $title, $privacy, $submit));

老实说,除了明显地创建一个选择框并用指定的值填充它之外,我并不完全确定这段代码的作用。

因此,如果用户选择“所有人”,每个人都应该能够删除和编辑该 cd,依此类推。

显然,我认为控制器必须有一些代码可以处理确定用户是否有权查看每个 cd 等。

所以扫描 Poll 控制器我发现这是在控制器的 init 函数中:

public function init() {
    // Get subject
    $poll = null;
    if( null !== ($pollIdentity = $this->_getParam('poll_id')) ) {
        $poll = Engine_Api::_()->getItem('poll', $pollIdentity);
        if( null !== $poll ) {
            Engine_Api::_()->core()->setSubject($poll);
        }
    }

    // Get viewer
    $this->view->viewer = $viewer = Engine_Api::_()->user()->getViewer();
    $this->view->viewer_id = Engine_Api::_()->user()->getViewer()->getIdentity();

    // only show polls if authorized
    $resource = ( $poll ? $poll : 'poll' );
    $viewer = ( $viewer && $viewer->getIdentity() ? $viewer : null );
    if( !$this->_helper->requireAuth()->setAuthParams($resource, $viewer, 'view')->isValid() ) {
        return;
    }
}

在顶部的每个操作中,它们都有一些不同的授权代码,一个这样的例子就是editAction顶部有这个代码:

// Check auth
if( !$this->_helper->requireUser()->isValid() ) {
    return;
}
if( !$this->_helper->requireSubject()->isValid() ) {
    return;
}
if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'edit')->isValid() ) {
    return;
}

同样在同一个动作中还有其他几个我不明白他们在做什么的位,下面是editActionPoll 控制器中的随机片段:

$auth = Engine_Api::_()->authorization()->context;
$roles = array('owner', 'owner_member', 'owner_member_member', 'owner_network', 'registered', 'everyone');

// Populate form with current settings
$form->search->setValue($poll->search);
foreach( $roles as $role ) {
    if( 1 === $auth->isAllowed($poll, $role, 'view') ) {
        $form->auth_view->setValue($role);
    }
    if( 1 === $auth->isAllowed($poll, $role, 'comment') ) {
        $form->auth_comment->setValue($role);
    }
}

// CREATE AUTH STUFF HERE
if( empty($values['auth_view']) ) {
    $values['auth_view'] = array('everyone');
}
if( empty($values['auth_comment']) ) {
    $values['auth_comment'] = array('everyone');
}

$viewMax = array_search($values['auth_view'], $roles);
$commentMax = array_search($values['auth_comment'], $roles);

我的问题是我真的不太了解上述任何一个,并且在坐了几天并且用谷歌搜索我的手指受伤之后,我仍然不知道我是否 100% 诚实。可以为我清除以上任何内容,帮助向我解释事情,如果可能的话,我如何将我想要的权限应用于我的模块。

4

2 回答 2

7

我将简要介绍如何使用授权,但是需要通过查看 SocialEngine 的代码来推断出更详细的信息。请注意,虽然我们不为 SocialEngine 编译文档,但我们的开发人员在我们的代码中使用了 PHPDocumentor 样式语法,您可以使用像 Neatbeans (http://netbeans.org/) 这样的 IDE 来快速访问该信息。

SocialEngine 有一些控制器动作助手类,用于在动作控制器中进行查询授权:

  • application/modules/Authorization/Controller/Action/Helper/RequireAuth.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireAbstract.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireAdmin.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireSubject.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireUser.php

在大多数情况下,您唯一关心的是这些:

  • application/modules/Authorization/Controller/Action/Helper/RequireAuth.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireSubject.php
  • 应用程序/模块/Core/Controller/Action/Helper/RequireUser.php

可以在 Album_AlbumController 类中找到如何使用这些帮助程序的一个很好的示例:application/modules/Album/controllers/AlbumController.php

public function init()
{
if( !$this->_helper->requireAuth()->setAuthParams('album', null, 'view')->isValid() ) return;

if( 0 !== ($photo_id = (int) $this->_getParam('photo_id')) &&
null !== ($photo = Engine_Api::_()->getItem('album_photo', $photo_id)) )
{
Engine_Api::_()->core()->setSubject($photo);
}

else if( 0 !== ($album_id = (int) $this->_getParam('album_id')) &&
null !== ($album = Engine_Api::_()->getItem('album', $album_id)) )
{
Engine_Api::_()->core()->setSubject($album);
}
}

public function editAction()
{
if( !$this->_helper->requireUser()->isValid() ) return;
if( !$this->_helper->requireSubject('album')->isValid() ) return;
if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'edit')->isValid() ) return;

init 函数中的代码简单地设置访问页面的要求,然后在 editAction 函数中对授权数据进行检查。requireSubject 和 requireUser 助手非常简单:

  1. requireSubject 期望页面的主题被设置,在上面的例子中是在 init 函数中完成的
  2. requireUser 检查查看者是否是登录用户

requireAuth 帮助器不太直接。为简洁起见,我将省略大部分抽象的内部工作。最后,helper 指向 Authorization_Api_Core::isAllowed 函数:application/modules/Authorization/Core/Api.php

/**
* Gets the specified permission for the context
*
* @param Core_Model_Item_Abstract|string $resource The resource type or object that is being accessed
* @param Core_Model_Item_Abstract $role The item (user) performing the action
* @param string $action The name of the action being performed
* @return mixed 0/1 for allowed, or data for settings
*/
public function isAllowed($resource, $role, $action = 'view')

函数期望的 $resource 和 $role 对象是 Zend_Db_Table_Row 的实例,在 SocialEngine 中被称为模型,并且期望位于模块的模型目录中。当 isAllowed 函数被调用时,授权 api 将针对 engine4_authorization_allow、engine4_authorization_levels 和 engine4_authorization_permissions 表查询数据库。

  1. engine4_authorization_levels 表包含由 SocialEngine 开箱即用创建的成员级别,以及从管理面板中的“管理”>“成员级别”部分创建的自定义成员级别。
  2. engine4_authorization_permissions 表包含所有默认和管理员指定的权限处理,例如成员级别设置。
  3. engine4_authorization_allow 包含单个对象的权限数据。例如,关于谁能够查看相册的信息将被放置在那里。是否允许 engine4_authorization_allow.role_id(映射到模型的项目 ID)访问 engine4_authorization_allow.resource_id(映射到模型的项目 ID)由 engine4_authorization_allow.value 列确定,该列应包含数字 0-5。

应用程序/模块/授权/Api/Core.php

class Authorization_Api_Core extends Core_Api_Abstract
{
/**
* Constants
*/
const LEVEL_DISALLOW = 0;
const LEVEL_ALLOW = 1;
const LEVEL_MODERATE = 2;
const LEVEL_NONBOOLEAN = 3;
const LEVEL_IGNORE = 4;
const LEVEL_SERIALIZED = 5;

0) 不允许访问链接的资源。这与允许表中不存在的行相同

1) 也允许访问链接的资源

2) 允许访问和管理资源(即超级管理员、管理员和版主成员级别)

3-5) 被忽略为不允许。这些期望一些自定义逻辑以便适当地处理授权。

于 2012-08-31T18:29:30.983 回答
1

我也不熟悉 SocialEngine,但经常使用 Zend Framework。我会尽量给你一些提示,如果需要的话,希望其他人可以为你补充更多。

看起来 SE在您刚刚展示的大部分代码中都使用了Zend_AuthZend_Acl 。

理解Zend_Auth是有帮助的,但所有这部分都已经完成,超出了你想要做的大部分事情。 Zend_Acl是您可能会花费大量时间阅读的内容。

Zend_Auth理解和之间区别的关键概念Zend_Acl是对Zend_Auth用户进行身份验证。也就是说,它根据某处的数据库检查提供的凭据,并说这个人就是他们所说的人,因为他们提供了正确的身份(例如,用户名和密码匹配)。 Zend_Acl另一方面,用于根据角色允许或拒绝对给定资源的访问。

简而言之,与允许用户Zend_Auth什么无关,只是他们是他们所说的那个人。 Zend_Acl表示用户有权或无权访问特定特性或功能(资源)。

我没有查看他们的代码来确认这一点,但Engine_Api::_()->user()->getViewer()->getIdentity();似乎正在提取用户的身份,乍一看似乎是数据库null中的用户或用户的身份id。他们可以使用它来判断一个人是否登录。

接下来,他们似乎正在调用一个名为的操作助手requireAuth,它可以设置身份验证参数或检查用户是否具有访问权限。这是基于 ZF 构建的 Social Engine 的一部分,不是 ZF 特定的,因此您可能需要阅读更多关于该助手如何工作的文档。

我认为这个助手只是一种间接的调用方式Zend_Acl::isValid()来确定用户的角色是否可以访问特定的资源。 Zend_Acl工作很简单。resources您可以根据role尝试访问它们来授予或拒绝对某些的访问。默认情况下,除非特别允许,否则拒绝访问所有资源。

这个插件可能做的是创建一些新资源,poll然后控制用户可以做什么view,或者edit一个特定的投票。

如果您继续阅读Zend_Acl,应该会清楚地了解更多代码。然后你所要做的就是弄清楚插件是如何存储角色和资源的。我猜有一种标准方法可以将其存储在社交引擎中,并且 ACL 规则会在给定用户的每个请求上自动设置。

希望对一些人有所帮助。

于 2012-07-17T21:14:00.557 回答