Я создаю веб-сайт, на котором я буду управлять пользователями и их разрешениями. Я ищу для реализации пользовательских ролей и, похоже, не могу обернуть голову тем, как все должно работать. Я хочу, чтобы иметь возможность назначить пользователю определенную роль, и каждая роль содержит от одного до нескольких разрешений, которые могут быть легко прочитаны моим сценарием. Просто хочу знать, как мне нужно настраивать мою базу данных, чтобы сделать это легко и эффективно.
В моей голове я рисую 3 таблицы (пользователи, роли и разрешения). Я могу предоставить каждому пользователю идентификатор роли, который объединяет таблицу ролей, я просто не знаю, как я могу связать роли с несколькими правами.
Я просто не знаю, как я могу связать роли с несколькими разрешениями.
Вы используете таблицу join: 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
Вот как я обычно делаю:
Вы определяете набор разрешений, значение которых варьируется от целевого объекта до целевого объекта, но общий смысл которого тот же. Например:
Затем вы назначаете бит каждому из них:
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']; }
Вы также можете добавить разрешения запрета с небольшими трудностями.
Я считаю, что побитовый оператор – лучший способ реализовать пользовательское разрешение. Здесь я показываю, как мы можем реализовать его с помощью 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
Если вы хотите пройти маршрут из трех таблиц, вы можете создать свои таблицы следующим образом:
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