我本来想问一个问题,关于我对某些用户/角色数据库表的设计是否可以接受,但经过一些研究后,我遇到了这个问题:

处理多种权限类型的最佳方法是什么?

这听起来像是一种创新方法,因此我没有使用多对多关系的 users_to_roles 表,而是将多个权限定义为单个小数(我认为是 int 数据类型)。这意味着单个用户的所有权限都位于一行中。在您阅读其他问题和答案之前,它可能不会有意义

我无法思考这个问题。有人可以解释一下转换过程吗?听起来“正确”,但我只是不明白在进入数据库之前如何将角色转换为小数,以及当它从数据库出来时如何转换回来。我正在使用 Java,但如果您将其删除,那也很酷。

这是原始答案,以防其他问题被删除:

“就我个人而言,我有时会使用标记的权限枚举。这样您就可以对枚举项使用 AND、OR、NOT 和 XOR 位运算。

[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}

然后,您可以使用 AND 位运算符组合多个权限。

例如,如果用户可以查看和编辑用户,则运算的二进制结果为 0000 0011,转换为十进制为 3。然后,您可以将一个用户的权限存储到数据库的单个列中(在我们的例子中为 3)。

在您的应用程序中,您只需要另一个按位运算 (OR) 来验证用户是否具有特定权限。”

有帮助吗?

解决方案

您使用按位运算。伪代码类似于:

bool HasPermission(User user, Permission permission) {
    return (user.Permission & permission) != 0;
}

void SetPermission(User user, Permission permission) {
    user.Permission |= permission;
}

void ClearPermission(User user, Permission permission) {
    user.Permission &= ~permission;
}

权限是您的帖子中定义的枚举类型,尽管无论它是什么类型都需要基于类似整数的类型。这同样适用于 User.Permission 字段。

如果这些运算符(&、|= 和 &=)对您来说没有意义,那么请阅读按位运算(按位 AND 和按位 OR)。

其他提示

实际上,这就是我们在我担任 DBA 的相当大的 Web 应用程序中确定权限的方式。

如果您打算做这样的事情,那么您将真正受益于 数字表. 。它将使你的计算速度更快。

基本设置包括下表:

  1. 组 - 用于执行多对多用户和安全点
  2. 安全点 - 包含匿名授权值和不属于单独组的经过身份验证的用户的值
  3. 组安全点连接表
  4. 一个特殊的 BitMask 数字表,其中包含 ^2 值的条目。因此,对于 2 (2) 有一个条目,对于三 (2 和 1) 有两个条目。这使我们不必每次都计算值。

首先我们判断用户是否登录。如果不是,我们将返回安全点的匿名授权。

接下来,我们通过简单的方法确定用户是否是与安全点关联的任何组的成员 EXISTS 用一个 JOIN. 。如果不是,我们将返回与经过身份验证的用户关联的值。在我们的系统上,大多数匿名和经过身份验证的默认值都设置为 1,因为我们要求您属于特定组。

笔记: 如果匿名用户没有访问权限,界面会将他们扔到登录框中,以允许他们登录并重试。

如果用户 一个或多个组的成员,然后我们从 BitMask 表中为为组定义的每个值选择不同的值。例如,如果您属于三个组,并且其中一个授权级别为 8,一个授权级别为 12,最后一个授权级别为 36,则我们对位掩码表的选择将分别返回 8、8 和 4,以及 4 和 32。通过执行不同操作,我们得到数字 4、8 和 32,它们正确地位掩码为 101100。

该值作为用户授权级别返回并由网站处理。

合理?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top