3

我正在考虑使用 Zend_ACL。但是,在我看来,您似乎创建了角色,然后将这些角色授予控制器和他们可以或不能访问的操作的权限。

然而,对我来说,这似乎相当有限。过去我创建了一个用户权限系统,在其中存储了 user_id、模块、控制器和他们可以访问的操作,但是我从未给他们一个组。因此,每个用户、每个模块、每个控制器、每个操作都基于他们可以访问的内容。

所以!我想知道我是否想减少组的限制,我应该给用户一个组并默认设置这些组权限。然后加载我的用户特定角色并覆盖默认组设置的角色:你们会这样做吗?

4

4 回答 4

3

您绝不限于使用角色系统来表示Zend_Acl.

例如:

在一个应用程序中,我有我的基本用户对象,实现Zend_Acl_Role_Interface它,在这种情况下返回一个特定于用户的字符串。为简单起见,我们只说类似 的user-1内容,其中数字部分是用户的唯一 ID。

当用户对象被初始化时,它会将自己添加到 ACL 中,用户特定的角色继承自更通用的角色(类似于组):

if(!$acl->hasRole($this)) {
    $acl->addRole($this, $this->role); // Let's say role == 'member' here
}

这允许您为父角色(或角色,您可以将数组作为第二个参数传递给 addRole,以拥有多个父角色)设置一般规则。此外,请记住角色在树上一直沿袭,因此父角色在这种情况下,角色本身也可能具有父角色。)

所以,为了说明这里的灵活性,让我们假设这个基本的 ACL 设置(这都是理论上的,我写它只是为了这个答案的目的):

$acl->addRole('guest');
$acl->addRole('member', 'guest');

$acl->allow('guest', 'comments', 'read');
$acl->allow('member', 'comments', 'write');

$user = $My_User_Model->find(1);
$acl->allow($user, 'comments', 'moderate');



$acl->isAllowed($user, 'comments', 'read'); // true
$acl->isAllowed($user, 'comments', 'write'); // true
$acl->isAllowed($user, 'comments', 'moderate'); // true

$acl->isAllowed('member', 'comments', 'moderate'); // false

等等...

Zend Framework 组件的美妙之处在于您完全不受限于以一种特定方式使用它们。是的,虽然这有时会让人望而生畏,并且通常需要在初始规划和实施上投入更多时间,但从长远来看,这是非常好的。

此外,就个人而言,我不喜欢将 ACL 权限直接映射到控制器/操作构造。但那是完全不同的对话。

于 2010-07-01T18:53:39.680 回答
0

你在正确的轨道上。

没有严格定义的“组”或“用户”的概念。

你只有角色。你可能有一个像“编辑”这样的角色,它可以访问某些资源(比如一个特定的动作,甚至是一些“文章”对象)。您可能还有一个像 user_1234 这样的角色,它可能有额外的规则。

您会将这两个角色都分配给 id 为 1234 的用户。

于 2010-06-29T17:20:14.917 回答
0

回复上述(我的回复很长)

是的,我不喜欢那样做。我宁愿为该特定用户加载一个数组:

$item['Movie'] = 1;
$item['Movie']['manage']['edit'] = 0;

然后做一个插件,加载这些权限(从数据库,到一个数组中)查看当前模块/控制器/动作并检查。

if (isset($item[$module]) && $item[$module] == 1) {
   if (isset($item[$module][$controller][$action]) && $item[$module][$controller][$action] == 0) {
       return false;
   }
   return true;
} else { 
 return false;
}

然后在我的引导程序中,如果它为假,则抛出异常。(请记住,这是针对我网站的管理区域,而不是前端,所以我对一般用户访问权限并不在意。

此外,我将该数组传递到视图并在链接上执行简单的 if 语句:

<?php if ($this->userPermission['Movie']['manage']['edit'])) { ?>
<a href="/administration/Movie/manage/edit/id/1">Edit Movie</a><?php } ?>

不利的一面是,如果该方法更改了控制器,我将不得不编辑模板。但是,我从我读过的教程中没有看到 Zend_ACL 视图的实现,所以我不确定它是否与我在那里做的有很大不同。

于 2010-06-29T17:29:56.080 回答
0

感谢您的反馈,但我决定创建自己的。如果有人感兴趣:

public function verify($controller=NULL, $action='index', $module='administration') {

    if ((isset($this->object[$module]['all']) && is_string($this->object[$module]['all'])) || isset($this->object[$module][$controller][$action]) || (isset($this->object[$module][$controller]) && is_string($this->object[$module][$controller]))) {
        return true;
    }
}

public static function check($values) {

    $module         = $values['module']     ? $values['module']     : 'administration';
    $controller     = $values['controller'] ? $values['controller'] : 'index';
    $action         = $values['action']     ? $values['action']     : 'index';
    $user_id        = $values['user_id'];

    $db    = Zend_Registry::get('dbAdapter');
    $query = $db->prepare(" 
        SELECT * 
        FROM `".self::table_name."` 
        WHERE 
            (
                (`module` = :module AND `controller` = :controller AND `action` = :action) OR
                (`module` = :module_2 AND `controller` = :controller_2 AND `action` = '') OR 
                (`module` = :module_3 AND `controller` = '' AND `action` = '')
            )
        AND enabled = 1 
        AND user_id = :user_id      
        ");

    $query->bindValue('module',         $module);
    $query->bindValue('module_2',       $module);
    $query->bindValue('module_3',       $module);
    $query->bindValue('controller',     $controller);
    $query->bindValue('controller_2',   $controller);
    $query->bindValue('action',         $action);
    $query->bindValue('user_id',        $user_id);

    $query->execute();
    $item = $query->fetch(PDO::FETCH_OBJ);
    $query->closeCursor();

    if (is_object($item)) {
        return $item;
    } else {
        throw new exception("Could not load user permission for this page ($module, $controller, $action)");
    }
}

在视图中:

    <?php if ($this->user_permissions->verify('movie')) { ?>
        <li class="parent">
            <img src="/design/images/icon/dvd.png" /> <span class="highlighter"><a href="/administration/movie/index">Movie</a></span>
            <?php if ($this->user_permissions->verify('movie', 'add')) { ?>
                 | <a href="/administration/movie/add">Add</a>
            <?php } ?>
            <?php if ($this->user_permissions->verify('movie', 'featured')) { ?>
                <ul>
                    <li>
                        <img src="/design/images/icon/order.png" /> <a href="/administration/movie/featured">Order Featured</a>
                    </li>
                </ul>
            <?php } ?>
        </li>
    <?php } ?>
于 2010-07-05T14:43:33.953 回答