我已经尝试了很多关于权限的不同的方案,我已经永远只找到了一个方法,使他们的工作满足程序员和客户端在几乎所有情况下。这是为了让他们部分受数据驱动。
我最近的一个尝试是这样的:
- 每个用户连接到它的权限对象。在我的情况下,当用户被请求时自动创建。 (在我的情况下,权限可以针对不同部分的不同,所以用户可能被允许用于Y做X而不是Z.)
- 每个页面,需要被宽容的代码块,或视图是包裹着一个如果语句检查权限对象。如果该权限也需要担心该部分,则将当前相关的部分ID作为数组传递,返回一组新的布尔值以进行匹配。
- 接口然后不直接向用户暴露这个复杂的混乱,而是一个superadmin接口允许创建新的用户类型。这些类型携带将为该'类型'的用户启用的权限集。不同类型的权限可能会有重叠,因此管理员和编辑者都可以“编辑复制”或其他内容。
- 正常的管理界面让个人用户可以设置为不同部分的不同用户类型。因此,一个用户可能是第2部分的管理员,第2,第3,第4和第5部分的编辑者。它们也可以在全局范围内设置,从而重载未使用的部分(0)。
这有很多好处,一个缺点。首先,缺点。因为这些密钥直接放入代码中,所以只有superadmin(又名开发人员)才能访问该部分接口。实际上,根本不需要接口,因为权限列表只应随代码而改变。真正的问题在于,在运行代码之前,您不会知道标题有什么问题,因为语法会很好。现在,如果这是用C#编写的,这将是一个非常严重的问题。但几乎所有的PHP都不是安全的,所以它对于课程来说确实是不合格的。这些值也可以从配置文件中加载,甚至可以从您构建用户类型的GUI中加载,尽管这似乎是错误的。
您从此获得什么能力,建立新的权限类型的飞行。您可以相对容易地重命名这些权限。 (由于系统只使用数字,因此标题仅用于捕获数字,因此可以在几个地方轻松更改)。代码使用起来非常简单。这将是这个样子:
if($current_user->permissions->can("View Sales Records"))
{
//Code to view sales records
}
或者稍微复杂
$sections = array(1,2,3,4); //Probably really a list of all sections in the system
$section_permissions = $current_user->permissions->these($sections)->can("Edit Section");
foreach($sections as $s)
{
if($section_permissions[$s])
{
// Code for maybe displaying a list of sections to edit or something
}
}
的方法链接很简单了。 ->these()
将内部数组设置为这些值,然后返回对该对象本身的引用。 ->can()
然后作用于该列表,如果它存在,然后取消它。在我自己的版本中,我也有->any()
它总是返回一个完整的部分列表,所以我可以检查->any()->can()
。
最后,许可对象还包含一个用户是什么类型的列表。这使得显示用户列表和激活的权限变得非常简单。在我的情况下,我们只需使用->types()
来访问该列表中的一个数组ids => names
。
不存在的权限标题被忽略。它们还以小写字母和空格和特殊字符进行匹配,以帮助减少输入错误带来的问题。我考虑过甚至在进行levenshtein距离检查并选择最接近的比赛。但最终最好不要依赖这样的事情。 (可能会记录错误,但优雅地选择最接近的匹配。)
在代码和界面之外,用户只需要在一个So-in-so中相互关联即可,这是一个Admin,Editor,Publisher ,作家,首席执行官等等。为不同的组织创建不同组的用户类型也是微不足道的。
的这一切部件可以大量缓存,建立一个基本的用户在所有还没有登录谁的人是很容易的,我还没有遇到那个不明显一个基于权限的问题用这个结构来解决。
我只希望我可以与你分享实际的代码。我自己并不拥有它,因此不能发布它。
我也很想找到这个答案。我们正在使用派对模型,并考虑使用自己的断言在应用程序中扮演'客户'的角色(在Zend ACL中说),但它看起来很笨重。 – boatingcow