【问题标题】:How to manage User Roles in a Database?如何管理数据库中的用户角色?
【发布时间】:2011-03-13 22:03:39
【问题描述】:

我正在创建一个网站,我将在其中管理用户及其权限。我正在寻找实现用户角色,并且似乎无法理解事情应该如何工作。我希望能够为用户分配某个角色,并让每个角色包含一个到多个权限,我的脚本可以轻松读取这些权限。只是想知道我应该如何设置我的数据库以轻松高效地完成此操作。

在我的脑海中,我描绘了 3 个表(用户、角色和权限)。我可以给每个用户一个加入角色表的角色 ID,我只是不知道如何将角色链接到多个权限。

【问题讨论】:

    标签: php mysql database-design


    【解决方案1】:

    我们使用 json 数据类型管理了两个表,因此我们不需要任何重复的条目,例如

    
    Role_ID Permission_ID
    1       1    
    1       2 
    
    Role Table
    
    id, role_name
    '1', 'read'
    '2', 'write'
    '3', 'update'
    '4', 'all'
    
    User Table
    
    id,   name,   role_assign, role_type
    '1', 'arjun', '[1, 2]',    'admin'
    '2', 'dhruv', '[3, 4]',    'user'
    
    Query
    
    SELECT u.id,r.role_name,u.name FROM test.users u inner join
    test.role r on JSON_CONTAINS(u.role_assign, cast(r.id as json));
    
    Output
    
    id,  role_name, name
    '1', 'read',   'arjun'
    '1', 'write',  'arjun'
    '2', 'update', 'dhruv'
    '2', 'all',    'dhruv'
    

    【讨论】:

      【解决方案2】:

      我认为按位运算符是实现用户权限的最佳方式。 这里我展示了我们如何使用 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' 拥有 'User-Add' (bit=1) 和 'Blog-Delete' (bit-64) 的权限,那么角色将为 65 (1+64)。
      如果用户 'Mehata' 拥有'Blog-View' (bit=128) 和'User-Delete' (bit-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://goo.gl/ATnj6j

      【讨论】:

        【解决方案3】:

        我只是不知道如何关联角色 多个权限。

        您使用连接表:role_id 和 permission_id 来识别哪些权限与哪些角色相关联

        编辑:

        示例表

        角色表

        Role_ID Role_Name
        1       Standard User
        2       Super User
        3       Guest
        

        权限表

        Permission_ID Permission_Name
        1             View User List
        2             Update Own User Account
        3             Update Any User Account
        

        ROLE_PERMISSION 表

        Role_ID Permission_ID
        1       1    // Role 1 (Standard User) grants View User List
        1       2    //        and Update Own User Account
        2       1    // Role 2 (Super User) grants View User List,
        2       2    //        Update Own User Account,
        2       3    //        and Update Any User Account
        3       1    // Role 3 (Guest) grants View User List
        

        列出指定 Role_ID 的权限

        select R.role_id,
               P.permission_id,
               P.permission_name
          from role R,
               permission P,
               role_permission RP
         where RP.permission_id = P.permission_id
           and RP.role_id = R.role_id
           and R.role_id = 1 
        

        【讨论】:

        • 太棒了。非常感谢你们。
        • +1 很好的例子。我认为这篇文章会被许多搜索此类信息的用户引用。
        • 感谢@Mark,非常好的帮助。现在,假设我有一个角色平面设计师,他无权查看任何人的个人资料,但他自己的。我已经为他分配了一个用户来照顾,他需要访问用户的个人资料。我如何在数据库中存储他有权查看分配给他的任何个人资料?
        • @In God I Trust - 这有点复杂;我设置了“更新托管用户帐户”的第四个权限并创建另一个经理->用户关系表;将其绑定到第四个权限的安全代码中;可能会创建一个“经理”角色作为新角色的权限
        • @MarkBaker 谢谢,这是有道理的,我想有了这个建议,我可以在 manager_user 表中添加第三列,如果我也需要的话,可以将经理分配给项目。感谢您的宝贵时间,您帮助了我!
        【解决方案4】:

        这就是我通常的做法:

        您定义了一组权限,其含义因目标对象而异,但其一般含义相同。例如:

        • 阅读
        • 追加
        • 删除
        • 删除内容
        • 读取权限
        • 更改权限

        然后你为每个分配一个位:

        class Perms {
            const read           = 1;
            const write          = 2;
            const append         = 4;
            const delete         = 8;
            const deleteContents = 16;
            const readPerm       = 32;
            const changePerm     = 64;
            /* shortcuts */
            const fullControl    = 127; 
            const noControl      = 0;
        }
        

        然后,对于每种类型的对象,您都有一个表,您可以在其中插入对 (user, perms)(group, perms)(role, perms) 或您想要与权限关联的任何内容。

        您可以像这样查询用户(可能有多个角色)的权限:

        //this will depend on the database
        //you could also use whatever bitwise OR aggregate your database has
        //to avoid the foreach loop below
        $query = new Query(
            "select perm from objects_permissions as P ".
            "where P.id_object = \$1 and " .
            "   (P.role = any(\$2));",
            $obj->getId(), $user->getRoles()
        );
        
        $perms = 0;
        foreach ($query as $row) {
            $perms |= $row['perm']; 
        }
        

        您还可以轻松添加拒绝权限。

        【讨论】:

        • 我承认使用类似的机制来定义用户对应用程序中对象的访问;但用户/角色/权限机制类似于 OP 要求的访问一般 UI 功能(例如 UPLOAD_FILE 权限)
        • @Mark 我的方法是概括。如果我需要控制对上传文件的访问,我会定义一个“上传文件容器”并在此类对象中授予用户append 权限。然后您可以轻松添加其他相关权限,例如该容器上的deleteContents 可以允许删除上传的文件,read 将允许下载文件或列出它们等。
        【解决方案5】:

        如果你想走 3 个表的路线,你可以像这样创建你的表:

        Table       | Rows
        User        | id ; name ; dob ; permission_id ; etc...  
        Roles       | id ; add_post ; edit_post ; delete_post ; add_user ; etc...
        Permissions | id ; user_id ; role_id 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-14
          • 2016-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-05
          相关资源
          最近更新 更多