我如何实现论坛权限

时间:2010-05-30 02:14:35

标签: php mysql permissions object bitmask

我已经开始在我的MVC框架上用PHP开发一个论坛应用程序了,我已经到了为成员分配权限的阶段(例如:READ,WRITE,UPDATE,DELETE)。

现在,我知道我可以在我的数据库的user表下添加5列,并将它们设置为1 | 0,但如果我想添加其他规则,例如MOVE,那对我来说似乎太多了。

如何将这些权限动态分配给用户?

我听说过使用过掩码,但如果我能继续使用它,那将是非常好的。

你有一个如何实现这个的例子吗?

4 个答案:

答案 0 :(得分:4)

当表示为二进制时,最好理解权限位掩码,每个数字表示权限打开或关闭。因此,如果存在权限X,Y和Z,并且我只能访问X和Z,101将表示我拥有授予我的第一和第三权限,而不是第二权限。二进制数101等效于十进制数5,因此这将最终存储在数据库中。单个小整数是一个比字符串或几个小整数更有效的存储对象。

编辑:我意识到利用现有转换功能实现快速实施是多么容易。这是一个样本。

<?php
function bitmask_expand($n) {
  // 9 returns array(1, 0, 0, 1)
  return str_split(base_convert($n, 10, 2));
}

function bitmask_compact($a) {
  // array(1, 0, 0, 1) returns 9
  return (int) base_convert(implode($a), 2, 10);
}

$ns = range(0, 7);
foreach($ns as $n) {
  print_r($b = bitmask_expand($n));
  echo bitmask_compact($b), "\n\n";
}

如果使用循环,而不是回退到字符串,可能会获得更好的性能,但这很清楚地说明了原理。

答案 1 :(得分:3)

您描述的方法 - 存储在列中的个人权限 - 很简单,但会以灵活性为代价(正如您所注意到的那样)。

Zuul的方法更简单,与您的方法基本相同,只是它避免了任何“ALTER TABLE”语句的需要。但是,它没有规范化,不易查询,也不能自我记录。

这两种方法的另一个问题是,随着用户群的增长,您会发现保持每个人的权限设置正变得越来越困难。你会发现自己有很多需要完全相同特权的用户。然而,为了更改用户的权限(例如容纳新权限),您必须进入并将该权限添加到需要单独使用它的每个用户。主要的PITA。

对于论坛,您不太可能需要每用户权限管理。您更有可能拥有某些类别的用户,如匿名用户,登录用户,版主,管理员等。这将使其非常适合基于角色的访问控制(RBAC)。在此系统中,您可以为每个用户分配一个角色,并为该角色授予权限。权限将作为行存储在“权限”表中。所以简化的数据库模式看起来像:

PRIVILEGE
int id (primary key)
varchar description

ROLE_PRIVILEGE_JOIN
privilege_id (foreign key)
role_id (foreign key)

ROLE
int id (primary key)
varchar description

USER
int id (primary key)
int role_id (foreign key)

此模式用于许多处理用户权限的应用程序。添加任何人可能在权限表中作为一行的所有权限;添加任何用户可能在角色表中拥有的每个角色;并在role_privilege_join表中适当地链接它们。

唯一真正的缺点是因为使用了连接表,“can user X do Y”查询会慢一点。

答案 2 :(得分:1)

我会创建一个名为“角色”的表:

CREATE TABLE Roles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 rolename VARCHAR(30))

坚持你想要的任何权限。然后创建一个名为“UserRoles”的表来将用户链接到角色:

CREATE TABLE UserRoles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 UserId INT,
 RoleID INT)

灵活性高,易于构建(即工作流程,规则等) (我也会添加外键)

答案 3 :(得分:-1)

您无需复杂化,只需使用字段“ex:permissions”并执行以下操作:

  

$ permissions =“1; 1; 0; 1”;

     

您关心的地方是:

     

READ - 1(可以)

     

WRITE - 1(可以)

     

更新 - 0(不能)

     

DELETE - 1(可以)

然后,在检查时,只需使用“爆炸”,“;”......

通过这种方式,您可以随时应用更多权限类型而无需更改表格...这样您就可以缩小表格,提高查询速度!

这是解决您问题的方法:)