我已经开始在我的MVC框架上用PHP开发一个论坛应用程序了,我已经到了为成员分配权限的阶段(例如:READ,WRITE,UPDATE,DELETE)。
现在,我知道我可以在我的数据库的user表下添加5列,并将它们设置为1 | 0,但如果我想添加其他规则,例如MOVE,那对我来说似乎太多了。
如何将这些权限动态分配给用户?
我听说过使用过掩码,但如果我能继续使用它,那将是非常好的。
你有一个如何实现这个的例子吗?
答案 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(可以)
然后,在检查时,只需使用“爆炸”,“;”......
通过这种方式,您可以随时应用更多权限类型而无需更改表格...这样您就可以缩小表格,提高查询速度!
这是解决您问题的方法:)