代码之家  ›  专栏  ›  技术社区  ›  hash

设计用户角色和权限系统的最佳实践?

  •  39
  • hash  · 技术社区  · 17 年前

    我需要在使用php/mysql构建的Web应用程序中添加用户角色和权限系统。我希望具有以下功能:

    1. 一个根用户可以创建子根、组、规则和普通用户(所有权限)。
    2. 子根只能为自己的组(无组)创建规则、权限和用户。
    3. 用户可以根据按组根分配给他的权限访问由他或他的组创建的内容。

    我需要系统足够灵活,以便为内容分配新的角色和权限。

    我有一个 users 存储组键和其他信息的表。目前,我在每个内容表中使用两个feilds,即 createdBy CreatedByGroup ,并将其作为特定用户是否具有权限的点。但它不够灵活,因为对于每一个新内容,我都必须通过所有数据更新和权限更新。请通过讨论您的模式设计最佳实践来帮助我。

    5 回复  |  直到 7 年前
        1
  •  34
  •   Eran Galperin    10 年前

    符合你需要的模式被称为 role-based access control .

    PHP中有几个很好的实现,包括 Zend_Acl (良好的文件记录) phpGACL TinyACL . 大多数框架还以某种形式拥有自己的ACL实现。

    即使您选择滚动自己的解决方案,它也将帮助您审查那些因素充分的解决方案。

        2
  •  31
  •   Cœur Gustavo Armenta    7 年前

    我认为位运算符是实现用户权限的最佳方法。 这里我将展示如何使用MySQL实现它。

    下面是包含一些示例数据的示例表:

    表1 :用于存储权限名称的权限表,位类似于1、2、4、8。ETC(2的倍数)

    CREATE TABLE IF NOT EXISTS `permission` (
      `bit` int(11) NOT NULL,
      `name` varchar(50) NOT NULL,
      PRIMARY KEY (`bit`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    在表中插入一些示例数据。

    INSERT INTO `permission` (`bit`, `name`) VALUES
    (1, 'User-Add'),
    (2, 'User-Edit'),
    (4, 'User-Delete'),
    (8, 'User-View'),
    (16, 'Blog-Add'),
    (32, 'Blog-Edit'),
    (64, 'Blog-Delete'),
    (128, 'Blog-View');
    

    表2 :用于存储用户ID、名称和角色的用户表。角色将计算为权限总和。
    例子:

    如果用户“ketan”拥有“用户添加”(bit=1)和“博客删除”(bit-64)的权限,那么角色将为65(1+64)。
    如果用户'mehata'拥有'blog view'(位=128)和'user delete'(位-4)的权限,那么角色将是132(128+4)。

    CREATE TABLE IF NOT EXISTS `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) NOT NULL,
      `role` int(11) NOT NULL,
      `created_date` datetime NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
    

    样本数据

    INSERT INTO `user` (`id`, `name`, `role`, `created_date`)
       VALUES (NULL, 'Ketan', '65', '2013-01-09 00:00:00'),
       (NULL, 'Mehata', '132', '2013-01-09 00:00:00');
    

    用户的交存权限 登录后,如果要加载用户权限,可以在下面查询以获取权限:

    SELECT permission.bit,permission.name  
       FROM user LEFT JOIN permission ON user.role & permission.bit
     WHERE user.id = 1
    

    这里,user.role“&permission.bit是位运算符,它将输出为-

    User-Add - 1
    Blog-Delete - 64
    

    如果我们想检查特定用户是否具有用户编辑权限-

      SELECT * FROM `user` 
         WHERE role & (select bit from permission where name='user-edit')
    

    输出=无行。

    您还可以看到: http://sforsuresh.in/implemention-of-user-permission-with-php-mysql-bitwise-operators/

        3
  •  6
  •   Neil Barnwell    17 年前

    您可能不需要权限组。而是创建用户组,授予用户组权限,并将用户分组。用户还应该能够覆盖他们所在组的权限。如果一个用户在多个具有权限的组中,则拒绝应始终覆盖授予。

    综上所述:

    • 用户拥有零个或多个权限(grany、deny)
    • 用户在零个或多个组中
    • 组具有零个或多个权限(授予、拒绝)
        4
  •  6
  •   Buhake Sindi Tesnep    12 年前

    我有一个稍微不同的结构,但它应该可以作为参考。

    每个用户都有一个与之关联的“role”、“groupid”和groupid所指的组表。 然后我有三张许可表。

    PermissionMaster(FormName)
    

    PermissionChild(PermissionMasterID, PermissionName, Desc, DefaultValue, DependOn)

    PermissionGroupChild(GroupID, PermissionChildID, Allow)
    

    PermissionMaster包含权限所引用的名称/窗体/模块。PermissionChild将列出每个主控形状的所有可能权限,例如“创建”、“查看”、“编辑”、“删除”和“描述”(在第一个版本中没有此权限,即使是对于一个模块,权限设置太多也会使它变得混乱)。我允许添加更多的子级来具体地引用“changetimestamp”之类的函数,它还允许更具体的权限,而不是“edit”。

    PermissionGroupChild是PermissionChild和Group表之间的链接。每个组都将复制一组PermissionChild,并使用默认设置进行设置。然后我有了一个权限类,它为每个用户执行表查询和检查。我只在登录时加载它。然后,在每个表单/模块中,我检查它是否具有适当的权限,并正确地应用UI。

    至于角色,我只在登录配置页面使用它。角色值越小,排名越高。所以用户只能看到自己和角色值高于自己的角色。他/她可以编辑那些级别比自己低但不相似的。

        5
  •  2
  •   Meloman    9 年前

    我有组和用户(如Active Directory LDAP解决方案)。因此,如果我授予组访问权,我需要该组中的用户具有继承访问权。

    因此,基于下面的@suresh kamrushi答案,我做了如下:

    INSERT INTO `permission` (`bit`, `name`) VALUES
    (1,   'add-yes'),
    (2,   'add-no'),
    (4,   'edit-yes'),
    (8,   'edit-no'),
    (16,  'del-yes'),
    (32,  'del-no'),
    (64,  'view-yes'),
    (128, 'view-no');
    

    如果用户有位 00000000 ,我取前两位数 00 那意味着 add-yes add-no 从组权限继承。

    如果用户有位 01010110 ,我取前两位数 01 那意味着 不添加 将启用组权限,因此此用户没有添加权限。这个位表示用户只能查看。

    它还与父组一起工作。

    你觉得这个解决方案怎么样? 有人有更好的方法吗?