如何实现论坛权限

How can I implement forum privileges

提问人:RobertPitt 提问时间:5/30/2010 最后编辑:Michael PetrottaRobertPitt 更新时间:5/31/2010 访问量:613

问:

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

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

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

我听说过使用位掩码,但如果我能在继续之前完全理解它们,那就太好了。

你有没有一个例子来说明我如何实现这一点?

php mysql 权限 对象 位掩码

评论


答:

-1赞 Zuul 5/30/2010 #1

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

$permissions = “1;1;0;1";

你所关注的地方,它写道:

阅读 - 1 (can)

写入 - 1(可以)

UPDATE - 0(无法)

DELETE - 1(可以)

然后,在检查时,只需使用“分解”和“;”...

这样,您始终可以在不更改表的情况下应用更多权限类型...因此,您可以缩小表,并加快查询速度!

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

评论

1赞 Matchu 5/30/2010
这里的分号似乎没有必要,因为无论如何,每个权限位都只是一个字符。当你在存储一串二进制文件时,为什么不把它存储为小数,就像前面描述的位掩码原理一样?
0赞 Zuul 5/30/2010
是的,你的权利!这是一个示例,也许不是最好的示例,但用“;”分隔的值将使您能够在将来添加像 1 这样的权限;0;1;1a;0;<-(1a 是“可以”和“a”级),但同样你可以使用 12,其中“2”将是子级......
4赞 Matchu 5/30/2010 #2

权限位掩码在表示为二进制时最好理解,每个数字代表一个权限是打开还是关闭。因此,如果权限 X、Y 和 Z 存在,而我只能访问 X 和 Z,则表示我拥有授予我的第一个和第三个权限,但没有第二个权限。二进制数等同于十进制数,所以这就是最终存储在数据库中的内容。单个小整数是比一个字符串或几个小整数更有效的存储对象。1011015

编辑:我意识到利用现有的转换函数来快速实现是多么容易。下面是一个示例。

<?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赞 itchi 5/30/2010 #3

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

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)

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

评论

0赞 Sasha Chedygov 5/30/2010
我认为这对 OP 想要的东西来说有点矫枉过正。一个简单的位掩码就可以了。
0赞 itchi 5/30/2010
我想我应该问问他的应用程序的范围和大小。PhpBB 实现了一个类似的结构,phpbb_user_group表。phpbbdoctor.com/doc_tables.php
3赞 alexantd 5/30/2010 #4

您描述的方法(存储在列中的单个权限)很简单,但牺牲了灵活性(正如您所注意到的)。

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表中适当地链接它们。

唯一真正的缺点是,由于使用了联接表,因此“用户 X 可以执行 Y 吗”查询会稍微慢一些。

评论

0赞 itchi 5/30/2010
很好地描述了位掩码和魔术字符串的陷阱。
0赞 RobertPitt 5/30/2010
谢谢你,我正在考虑位掩码,因为它还没有完全掌握,我认为在我做出关于权限系统如何工作的可靠决定之前,我应该确切地知道它们是什么以及它们是如何工作的,但现在你把它放在上下文中,这样就不需要位掩码,因为它只是使应用程序中的简单任务复杂化, 此外,当涉及到ACP中的权限管理时,这可以简化排序。谢谢