访问控制问题

时间:2011-06-11 22:37:02

标签: php arrays multidimensional-array access-control

我正在为我的项目开发一个访问控制库,我正在寻找最佳解决方案:

我将所有访问列表从数据库获取到数组。结果它看起来像这样:

$array = array(
    '*' => array('administrator' => TRUE),
    'frontend/*' => array(
        'user' => TRUE,
        'unregistered' => TRUE
        ),
    'backend/*' => array(
        'user' => FALSE,
        'unregistered' => FALSE
    ),
    'backend/user/*' => array(
        'moderator' => FALSE,
        'supermoderator' => TRUE,
    ),
    'backend/article/*' => array(
        'supermoderator' => TRUE
    ),
    'backend/article/add/new' => array(
        'moderator' => TRUE
    )
);

“*”表示此用户可以访问所有相关选项后端/ article / *表示该组可以访问所有文章选项(文章/添加,文章/删除,...)。

如您所见,backend/article/add中没有超级模拟器的项目,但它具有对所有文章页面的主访问权。

检查这个的最佳方法是什么?我试过array_walk(),但我想它不会帮助我。

感谢您的建议......

如果你愿意,我可以分享我的整个代码。

*编辑*

我存储错误吗?如果您有更好的解决方案来存储它,我将很高兴听到它。

感谢您提出建议

3 个答案:

答案 0 :(得分:0)

无论这是一个复杂的算法,简单的array_walk都不会。除非有人感到特别慷慨并会为你写一个,我建议你雇用一个程序员。


  

我存储错误吗?如果您有更好的解决方案来存储它,我将很高兴听到它。

这完全取决于你的算法。您可以编写一个使用当前数据格式的文件。如果更改数据格式,也可以编写更简单的文件。但是,你的数据格式应该是什么样的,那对于程序员来说,这是一项工作。

答案 1 :(得分:0)

我自己找到了答案:

让我们说用户试图访问超级模拟器组中的backend/article/add/new和此用户。所以我需要寻找backend/*backend/article/*backend/article/add/*array_slice()for()足以满足此要求:

我顺便使用CodeIgniter。我修改了一点来分隔前端和后端控制器。我没有使用application/controller目录。我正在为控制器使用application/backendapplication/frontend目录。

所以uri模式就是这样:http://site.com/[backend]*/[directory]*/class/method

// This is the page that user trying to reach
$requested_page = "backend/article/add/new";

// pharsing...
$x = explode('/', $requested_page);

// this is needed to cut last 3, 2, 1 items of $x
$i = count($x) > 3 ? -4 : -count($x);

for (; $i < 0; $i++) {
    $resource = implode('/', array_slice($x, 0, $i)) . '/*';
    // echoing for debug
    echo $resource;
}

// Outputs:
// backend/*
// backend/article/*
// backend/article/add/*

答案 2 :(得分:0)

function userHasPermissions($permissionsArray, $user, $path) {
    // Check exact
    if(isset($permissionsArray[$path]) &&
       isset($permissionsArray[$path][$user])) {
        return $permissionsArray[$path][$user];
    }

    // Check lower and lower
    $partArr = explode('/', $path);
    for($i = substr_count($path, '/'); $i >= 0; $i--) {
        if($i > 0) {
            $choppedPartArr = array_slice($partArr, 0, $i);
            $newPath = implode($choppedPartArr, '/') . '/*';
        } else {
            $newPath = '*';
        }

        if(isset($permissionsArray[$newPath]) &&
           isset($permissionsArray[$newPath][$user])) {
            return $permissionsArray[$newPath][$user];
        }
    }

    return false;
}

echo "Result: " . (userHasPermissions($array, 'supermoderator', 'backend/article/add') ? "true" : "false");

请注意,'backend / article'将为'supermoderator'返回false,因为'backend / article / *'与它不匹配。要更改此设置,只需将$i = substr_count($path, '/');更改为$i = substr_count($path, '/')+1;