Лучшая практика для разработки роли пользователя и системы разрешений?
Мне нужно добавить роли пользователя и систему разрешений в мое веб-приложение, построенное с использованием PHP/MySQL. Я хочу иметь эту функциональность:
- Один пользователь root может создавать подкорни, группы, правила и обычных пользователей (все привилегии).
- Под-корни могут создавать только правила, разрешения и пользователей для своей группы (без групп).
- Пользователь может получить доступ к контенту, созданному им или его группой, на основании присвоенного ему права, с помощью группового root.
Мне нужно, чтобы система была достаточно гибкой, чтобы новые роли и разрешения были назначены для контента.
У меня есть таблица хранения таблицы users
, а также другая информация. В настоящее время я использую две feilds в каждой таблице контента i.e. createdBy
и CreatedByGroup
, и используя это как точку, имеет ли определенный пользователь права. Но он не достаточно гибкий, потому что для каждого нового контента мне нужно пройти все обновления данных и обновления разрешений. Пожалуйста, помогите мне, обсудив ваши рекомендации по разработке схемы.
Ответы
Ответ 1
Образец, который соответствует вашим потребностям, называется ролевым контролем доступа.
В PHP есть несколько хороших реализаций, в том числе Zend_Acl (хорошая документация), phpGACL и TinyACL. Большинство фреймворков также имеют свои собственные реализации ACL в той или иной форме.
Даже если вы решите перевернуть свои собственные, это поможет вам просмотреть хорошо обоснованные решения, такие как.
Ответ 2
Я считаю, что побитовый оператор - лучший способ реализовать пользовательское разрешение.
Здесь я показываю, как мы можем реализовать его с MySQL.
Ниже приведены примеры таблиц с некоторыми примерами данных:
Таблица 1: таблица разрешений для хранения имени разрешения вместе с ним бит 1, 2, 4, 8 и т.д. (несколько из 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
Ответ 3
У меня была немного другая структура, но она должна быть в состоянии служить ссылкой.
Каждый пользователь имеет ассоциированную с ним роль "Роль", "Групповой идентификатор" и таблицу "Группа", к которой относится идентификатор группы.
Тогда у меня есть 3 таблицы разрешений.
PermissionMaster(FormName)
PermissionChild(PermissionMasterID, PermissionName, Desc, DefaultValue, DependOn)
и
PermissionGroupChild(GroupID, PermissionChildID, Allow)
PermissionMaster содержит имя/форму/модуль, к которым относится разрешение. PermissionChild отобразит все доступные разрешения для каждого мастера, такие как "Создать", "Вид", "Изменить", "Удалить" и описание (у меня не было этого в первой версии, и он начал запутываться когда имеется слишком много настроек разрешения даже для 1 модуля). Я разрешаю добавлять больше детей, чтобы конкретно ссылаться на некоторую функцию, например "ChangeTimeStamp", которая также разрешала бы более конкретное разрешение, а затем "Редактировать"
Затем PermissionGroupChild - это ссылка между таблицей PermissionChild и Group. Каждая группа будет иметь набор PermissionChild, скопированный и настроенный с настройкой по умолчанию. Затем у меня был класс разрешений, который выполняет запрос таблицы и проверяет каждого пользователя. Я загружаю его только во время входа в систему. Затем в каждой форме/модуле я проверяю соответствующее разрешение и правильно применяю интерфейс.
Что касается роли, я использую ее только на странице конфигурации входа. Меньшее значение роли означает более высокий рейтинг. Таким образом, пользователь может видеть только себя и значение роли выше самого себя. Он/она может редактировать те, которые имеют более низкий ранг, чем сам, но не похожий.
Ответ 4
Возможно, вам не нужны группы разрешений. Вместо этого создайте группы пользователей, предоставите права групп пользователей и поместите пользователей в группы. Пользователи также должны иметь возможность переопределять разрешения от групп, в которых они находятся. Запрет должен всегда отменять грант, если пользователь находится в нескольких группах с pemission.
Вкратце:
- Пользователь имеет ноль или более разрешений (grany, deny)
- Пользователь находится в нуле или более группах.
- Группа имеет нулевое или большее количество разрешений (grant, deny)
Ответ 5
У меня есть группы и пользователи (например, решение 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
, что означает, что add-no
будет заполняться групповыми разрешениями, поэтому у этого пользователя нет разрешения на добавление. Это поразрядно говорит, что пользователь может просматривать только.
Он также работает с родительскими группами.
Что вы думаете об этом решении?
У кого-то есть лучший способ для этого?