3

我在 PHP 中创建了一个应用程序,它有用户并且用户有不同的级别,比如说 1、2、3、4。当用户登录时,它会设置一个会话,其中包含他们的级别号。该应用程序根据用户级别显示不同的页面,如下所示:

if($role_level > 3)
{
    //Show something
}

现在我想创建一个添加用户部分,用户可以在其中添加新用户并可能从下拉(html 选择)框中为他们定义一个角色。但他们只能定义一个低于自己的角色。我在想这样的事情:

<select>
    ("SELECT * FROM `roles` WHERE `roles_level` < $role_level)
    loop results into <options></options>
</select>

对此有何评论?更好的解决方法?以上会有影响吗?

4

6 回答 6

5

您的想法似乎可行,但它不是很灵活,因为它允许角色之间的单一直接层次结构。如果您需要分支角色怎么办?例如,您现在可能将“用户”、“发布者”、“审阅者”和“管理员”作为当前的 1、2、3 和 4。

用户只能阅读文章,出版商也可以撰写和编辑他们的文章,审稿人也可以编辑其他出版商的文章,管理员也可以做管理工作。

如果你想要一个主持人角色怎么办?版主可以编辑任何人的文章,但不能撰写新文章。你将如何实现它?你不能用你当前的模型。

建议你定义一个“roles”表,一个“actions”表,以及它们之间的NM关系表:

角色:

  • 1、用户
  • 2、出版商
  • 3、审稿人
  • 4、管理员
  • 5、article_moderator

行动:

  • 1、read_post
  • 2、write_post
  • 3、edit_own_post
  • 4、edit_others_post
  • 5、管理工具

Roles_Actions:

  • 1,1
  • 2,1
  • 2,2
  • 2,3
  • 3,1
  • 3,2
  • 3,3
  • 3,4
  • 4,1
  • 4,2
  • 4,3
  • 4,4
  • 4,5
  • 5,1
  • 5,4(注意版主 (5) 不能 write_own_post 甚至不能 edit_own_post 而只能 edit_others_post)

当然,这更复杂,但未来更灵活

我建议你也阅读这个答案: @Vyktor 的LINK,它解释了 ACL 概念,对大型项目很有用

于 2013-04-16T08:54:35.950 回答
2

我认为 STT LCU 已经提供了一个很好的答案,但是出于学习目的(是的,这只是一个扩展)我想添加示例如何在生产环境中(并且已经完成),我最喜欢的示例 - Zend Framework 的A ccess控制列表_ _

他们指定了三个单独的项目/对象/不确定如何调用它们:

  • 资源- 你指的是什么,这可以是大项目,如Forums, News, Articles... 或原子项目,如Forums_<forum_id>_others_posts_title. 这应该取决于您期望有多少用户以及结构的复杂程度。如果您只有 10 个用户和 1 个管理员,那么您可以为整个站点使用一个资源。另一方面......想象你是谷歌,有成千上万的应用程序在你的控制之下,你想提出统一和集中的 ACL 控制......很多很多很多资源。
  • 角色- 这应该是不言自明的,但示例:Banned, Visitor, User, ForumModerator, ArticlesModerator, SiteAdministrator. 在最佳框架(例如提到的 Zend)中,您可以构建层次结构并继承角色之间的访问权限。
  • 访问控制- Visitor can list list articles, but cannot read them...这又是一件应该很直观的事情,但这里有一点争议:
    • 使用层次结构- 假设您指定这样的层次结构none < list < read < write < create < edit < delete,并自动将您全部放在左侧,例如自动写入授予您读取和列出。这很好,很直观……但是当这种方法没用时,这里有一个例子:Black box,您希望用户在其中发布项目,而不是阅读它们。
    • 使用标志- **x chmod style* 访问由以下位置确定flag
      • 1 - 执行/列出目录内容
      • 2 - 写
      • 4 - 阅读
        Where you can use binary and to check access: access&WRITE,或使用具有大量列的 sql 模式。

总结一下:你可以做的事情很多,我真的建议阅读 Zend 的 ACL,这样你会感觉到 API 的外观,也许你会意识到一些你不会想到的可能的缺点自己的。

于 2013-04-16T09:29:23.317 回答
1

如果角色像你说的那样静态(1,2,3,4),那么我建议跳过额外的数据库命中并使用快速for循环!

<select>
<?php
for( $iRole = $role_level - 1; $iRole > 0; --$iRole )
    echo '<option value='.$iRole.'>'.$iRole.'</option>';
?>
</select>

否则,您似乎走在正确的轨道上。

于 2013-04-16T08:51:23.983 回答
1

好的,您可以拥有一个包含权限的表。如果级别数不多,您还可以创建不同的数据库帐户。对不同部分具有不同的访问权限。

并且要小心你应该检查这个人和他/她想做的事情。我的意思是仅仅显示一个选项是不够的,你应该检查服务器端的权限。

并且您可以像@STT LCU 所说的那样创建操作和用户(角色)。

但这还不够,因为您需要一个代码或类似权限检查器的类。使用它您可以检查权限。

if($perm->IsHaveAccess('editing_post')){
//the logic
}
于 2013-04-16T09:02:32.077 回答
1

您的问题有一个非常好的解决方案。它是 ACL(访问控制列表)。

有角色和资源,您可以访问它:)

Zend Site 有一个例子。

$acl = new Zend_Acl();

$acl->addRole(new Zend_Acl_Role('guest'))
    ->addRole(new Zend_Acl_Role('member'))
    ->addRole(new Zend_Acl_Role('admin'));

$parents = array('guest', 'member', 'admin');
$acl->addRole(new Zend_Acl_Role('someUser'), $parents);

$acl->add(new Zend_Acl_Resource('someResource'));

$acl->deny('guest', 'someResource');
$acl->allow('member', 'someResource');

echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';

更多关于http://framework.zend.com/manual/1.12/en/zend.acl.introduction.html

我被教导说,如果有一些东西写得很好并且有效,那么浪费时间去写新东西是没有意义的。

这些角色、资源和它们之间的关系可以保存在数据库中,并在需要时加载。

这是一个非常基本的示例,Zend_Acl 为您提供了一个非常强大的工具,这取决于您如何使用它。如果您不想使用 Zend Class,您可以查看它并以类似的方式设计您的类。

于 2013-04-16T09:13:31.053 回答
1

如果您知道您将拥有所有可用的数字(即,您不会选择 1、2、5、6、20),那么这样做会容易得多:

foreach(range(1,$role_level-1) as $level):
    echo "<option value='$level'>Level $level</option>";
endforeach;

而且,是的,你的想法将足够有效,可以做一个基本的权限系统。

于 2013-04-16T08:48:40.773 回答