如何管理数据库中的用户角色?

时间:2010-07-09 14:33:10

标签: php mysql database-design

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

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

5 个答案:

答案 0 :(得分:38)

  

我只是不知道如何链接角色   几个权限。

使用连接表: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 :(得分:5)

我认为按位运算符是实现用户权限的最佳方式。 在这里,我将展示如何使用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'获得用户添加'的许可(位= 1)和'博客 - 删除' (bit-64)所以角色是65(1 + 64) 如果用户' Mehata'获得“博客查看”的许可。 (位= 128)和'用户删除' (第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

答案 2 :(得分: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']; 
}

您也可以毫不费力地添加拒绝权限。

答案 3 :(得分:0)

如果你想走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 

答案 4 :(得分:0)

我们已经使用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'