我正在构建一个web应用程序,用户可以使用该应用程序相互分配任务。
用户都在局域网上。
已经有了一个基本的权限系统,其中用户角色要么是管理员,要么是普通用户。
我必须实现的是一些非常细粒度的东西。。。我想不出一个好的方法来做这个
以下是我需要控制的事情列表:
- 如果用户可以更改其他用户信息
- 如果用户可以通过VPN访问局域网(我认为这是另一个挑战)
- 用户只能将任务分配给一组其他用户(可能是所有用户,也可能是少数用户)
- 如果用户能够更改/删除其他用户已分配的任务
- 如果用户可以删除其他用户
- 如果用户可以更改其他用户的权限
我想要的是一个类似的例子,这样我就不必重新发明轮子了。或者可能有一个关于如何在尽可能少的头痛的情况下实现这一点的想法:P。此外,我不知道如何构建MySQL表来存储所有这些权限。
我曾想过为用户分配角色,但我需要更多的灵活性,而不仅仅是这些角色。
有什么想法吗?
一种简单的方法是在用户表中只增加一列,称为Access、Permission或类似的列。然后,对于您想要的每个权限,您可以定义一个常量,该常量具有可除以2的整数值或数字1,例如:
class PermissionChecker {
const CAN_CHANGE_OTHER_USERS_INFO = 1; // in bit form: 000001
const CAN_ACCESS_LAN_VIA_VPN = 2; // 000010
const CAN_ASSIGN_TASKS = 4; // 000100
const CAN_CHANGE_OTHER_USERS_TASKS = 8;// 001000
const CAN_DELETE_USERS = 16; // 010000
const CAN_CHANGE_USER_PERMISSIONS = 32;// 100000
public static function hasAccess($userAccess, $accessFlag) {
return $userAccess & $accessFlag; // The bitwise operation is the key....
}
}
$userAccess = 33; // read from database, in bit form: 100001
// check permissions like:
if (PermissionChecker::hasAccess($userAccess, PermissionChecker::CAN_CHANGE_OTHER_USERS_INFO)) {
// this will be true, because 100001 & 000001 returns 1
}
if (PermissionChecker::hasAccess($userAccess, PermissionChecker::CAN_CHANGE_USER_PERMISSIONS)) {
// this will be true as well, because 100001 & 100000 returns 1
}
if (PermissionChecker::hasAccess($userAccess, PermissionChecker::CAN_CHANGE_OTHER_USERS_TASKS)) {
// this will not happen... because 100001 & 001000 returns 0
}
然后,当需要另一个权限级别时,您只需添加另一个可除以2的数字,例如64、128等。也许这不是最漂亮的解决方案,但却是一个简单的解决方案。
当你想为用户存储权限时,你可以使用位或运算符,比如:
$userAccess = PermissionChecker::CAN_CHANGE_OTHER_USERS_TASKS |
PermissionChecker::CAN_CHANGE_OTHER_USERS_INFO; // will give $userAccess = 9;
// then store $userAccess in the database for current user...
一个选项是使用数据库表来存储权限,其中一行是单个权限。如果表中不存在给定user_id的权限,则该用户不具有该权限。
user_id | permission
-----------------------------
1 | CHANGE_USER_INFO
1 | DELETE_USERS
1 | CHANGE_USER_PERMISSIONS
2 | VPN_ACCESS
如您所见,用户1将能够更改信息、删除和更改权限。用户2只能访问VPN。这将很容易添加和删除权限,您只需要插入或删除即可。将来创建新的权限类型也很容易。
解决你的第3点。那会更复杂。为此,您可以使用另一个列为user_id
和target_user_id
的表,在其中插入用户可以向其分配任务的user_id
。或者,您可以将另一列添加到上面的表中,如通用ID,然后插入ASSIGN_TASK
并用目标用户填充ID列。
允许管理员定义角色,以及定义赋予每个角色的权力。这可以通过逐位比较(好)或多对多关系数据库表(更好)来完成。
这个系统给了你最大的灵活性,因为它可以很容易地添加新的能力,而无需重新配置整个角色系统。