当前位置: 首页 > 面试题库 >

ACL的数据库架构

陈翰林
2023-03-14
问题内容

我想为ACL创建一个架构;但是,我在实现它的两种方法之间陷入了困境。

我敢肯定,我不想处理级联权限,因为这会导致后端和站点管理员感到困惑。

我想我也可以只和一个角色一起生活。这样的设置将允许在网站扩展时根据需要html" target="_blank">添加角色和权限,而不会影响现有角色/规则。

首先,我要规范化数据并使用三个表来表示关系。

ROLES { id, name }
RESOURCES { id, name }
PERMISSIONS { id, role_id, resource_id }

查询以确定是否允许某处某个用户的查询如下所示:

SELECT id FROM resources WHERE name = ?
SELECT * FROM permissions WHERE role_id = ? AND resource_id = ? ($user_role_id, $resource->id)

然后我意识到我将只有大约20个资源,每个资源最多具有5个动作(创建,更新,查看等),可能还有8个角色。这意味着我可以公然无视数据规范化,因为我永远不会有数百条可能的记录。

因此,也许像这样的模式更有意义。

ROLES { id, name }
PERMISSIONS { id, role_id, resource_name }

这将允许我在单个查询中查找记录

SELECT * FROM permissions WHERE role_id = ? AND permission  = ? ($user_role_id, 'post.update')

那么哪个更正确? ACL是否还有其他架构布局?


问题答案:

以我的经验,真正的问题主要归结为是否将发生任何数量的特定于用户的访问限制。

例如,假设您正在设计社区的架构,并且允许用户切换其个人资料的可见性。

一种选择是坚持使用公共/私有配置文件标志,并坚持进行广泛的先占权限检查:“ users.view”(查看公共用户)与例如“
users.view_all”(查看所有用户,对于主持人) 。

另一个涉及更精细的权限,您可能希望他们能够进行配置,以便他们可以使自己(a)所有人都可以看到,(b)亲手挑选的伙伴可以看到,(c)完全保密,甚至(d
),但由他们手工挑选的bozo除外。在这种情况下,您需要为各个行存储与所有者/访问相关的数据,并且需要对其中的一些内容进行大量抽象,以避免实现密集的,面向图的传递闭包。

无论采用哪种方法,我都发现,角色编辑/分配中增加的复杂性被 分配 给各个数据段的权限所带来的轻松/灵活性所抵消,并且以下各项效果最佳:

  1. 用户可以具有多个角色
  2. 角色和权限合并在同一个表中,带有标志以区分两者(在编辑角色/权限时有用)
  3. 角色可以分配同一表中的其他角色,角色和权限可以分配权限(但权限不能分配角色)。

然后,可以在两个查询中提取生成的面向图,使用您使用的任何一种语言,在合理的时间内一劳永逸地构建所有内容,并将其缓存到Memcache或类似物中以供后续使用。

从那里开始,获取用户的权限就是检查他拥有哪些角色,并使用权限图对其进行处理以获取最终权限。通过验证用户是否具有指定的角色/权限来检查权限。然后基于该权限检查运行查询/发出错误。

如果需要,您可以扩展对单个节点的检查(例如check_perms($user, 'users.edit', $node),“可以编辑此节点”与check_perms($user, 'users.edit')“可以编辑一个节点”),并且最终用户可以使用非常灵活/易于使用的工具。

如开头的示例所示,请警惕过多地转向行级权限。性能瓶颈在检查单个节点的权限方面要比拉出有效节点列表(即仅用户可以查看或编辑的节点)少。如果您不太(非常)精通查询优化,则建议不要在行本身内的标志和user_id字段之外进行任何操作。



 类似资料:
  • 问题内容: 如何在Laravel模式构建器中创建一个? 在文档中说: 但是我需要一个MediumBlob,否则图像将在64K时被截断;我们正在运行MySQL。 我知道Laravel的架构生成器与数据库无关,但是有一种方法可以避免“本机方法”,如果没有,我该如何创建列? 问题答案: 你不能 该问题建议使用原始查询来创建此类列,因此您应该在迁移文件中执行以下操作:

  • 问题内容: 我正在开发一种多语言软件。就应用程序代码而言,可本地化性不是问题。我们可以使用特定于语言的资源,并拥有与之配合使用的各种工具。 但是,定义多语言数据库架构的最佳方法是什么?假设我们有很多表(100个或更多),每个表可以有多个可以本地化的列(大多数nvarchar列应该可以本地化)。例如,其中一个表可能包含产品信息: 我可以想到三种支持NAME和DESCRIPTION列中的多语言文本的方

  • 问题内容: 我正在使用Microsoft Sql Server Management Studio。我目前有一个包含数据的现有数据库,我将其称为DatabaseProd。我还有一个第二个数据库,其中包含用于测试的数据,因此数据既不完全正确也不是最新的。我将这个数据库称为DatabaseDev。 但是,DatabaseDev现在包含新添加的表和新添加的列等。 我想将此新模式从DatabaseDev复

  • 问题内容: 我目前正在使用jOOQ访问Java中的嵌入式H2数据库以生成表类等。我目前可以执行查询,例如 在我的代码中,返回结果等。 但是我不能查询信息架构。我可以使用H2控制台正常访问它,并且为给定的information_schema表创建视图可以正常工作。我的问题是我应该如何访问information_schema例如执行查询,例如 从我的Java代码中?我是否必须创建视图,是否可以通过jo

  • 是一个通用数据库处理框架(可以包含MSSQL POSTGRESQL,SQLITE EXCEL MYSQL DB2 ORACLE...只要你愿意实现接口就可以).很便捷地进行常用数据库操作(增删改查).其性能是几近纯ADO.NET.对于实体的查询采用emit实 现,如果您还不满意可用此框架的代码生成器直接生成纯ADO.NET SQL形式.其主要特色就是性能和便捷的操作.  

  • 问题内容: 我在使用JPA / Spring遇到一个特定问题时遇到了一些麻烦: 如何为实体动态分配架构? 我们有属于模式AD的TABLE1和位于BD下的TABLE2。 架构可能不会在注释属性中进行硬编码,因为它取决于环境(Dev / Acc / Prd)。(接受的模式是S1A和S2A) 我该如何实现?是否可以指定这样的占位符: 以便根据驻留在环境中的属性文件替换架构? 干杯 问题答案: 我有一个相