Как управлять ролями пользователей в базе данных?
Я создаю веб-сайт, на котором я буду управлять пользователями и их разрешениями. Я ищу для реализации пользовательских ролей и, похоже, не могу обернуть голову тем, как все должно работать. Я хочу, чтобы иметь возможность назначить пользователю определенную роль, и каждая роль содержит от одного до нескольких разрешений, которые можно легко прочитать с помощью моего script. Просто хочу знать, как мне нужно настроить мою базу данных, чтобы сделать это легко и эффективно.
В моей голове я рисую 3 таблицы (пользователи, роли и разрешения). Я могу дать каждому пользователю идентификатор роли, который присоединяется к таблице ролей, я просто не знаю, как я могу связать роли с несколькими правами.
Ответы
Ответ 1
Я просто не знаю, как я могу связать роли для нескольких разрешений.
Вы используете таблицу соединений: role_id и permission_id для определения того, какие разрешения связаны с какими ролями
EDIT:
Примеры таблиц
Таблица ROLE
Role_ID Role_Name
1 Standard User
2 Super User
3 Guest
Таблица PERMISSION
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
Ответ 2
Вот как обычно я делаю:
Вы определяете набор разрешений, значение которых изменяется от целевого объекта к целевому объекту, но общий смысл которого тот же. Например:
- прочитать
- записи
- Append
- удалить
- удалить содержимое
- права на чтение
- изменить права доступа
Затем вы назначаете бит каждому из них:
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
Я считаю, что побитовый оператор - лучший способ реализовать пользовательское разрешение.
Здесь я показываю, как мы можем реализовать его с помощью 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. Таблица пользователей для хранения идентификатора пользователя, имени и роли. Роль будет рассчитываться как сумма разрешений.
Пример:
Если пользователь "Ketan" имеет разрешение "User-Add" (бит = 1) и "Blog-Delete" (бит-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');
Разрешение пользователя Loding
После входа в систему, если мы хотим загрузить пользовательское разрешение, мы можем запросить ниже, чтобы получить разрешения:
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
Ответ 4
Если вы хотите пройти маршрут из трех таблиц, вы можете создать свои таблицы следующим образом:
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