Наилучшая практика для разработки пользовательских ролей и системы разрешений? - PullRequest
40 голосов
/ 02 декабря 2008

Мне нужно добавить пользовательские роли и систему разрешений в мое веб-приложение, построенное с использованием PHP / MySQL. Я хочу иметь эту функциональность:

  1. Один пользователь root может создавать подчиненных, групп, правил и обычных пользователей (все привилегии).
  2. Подкоренные пользователи могут создавать только правила, разрешения и пользователей для своей группы (без групп).
  3. Пользователь может получить доступ к любому контенту, созданному им или его группой, на основании назначенного ему разрешения корневым пользователем группы.

Мне нужно, чтобы система была достаточно гибкой, чтобы контенту были назначены новые роли и разрешения.

У меня есть users таблица, хранящая групповой ключ вместе с другой информацией. В настоящее время я использую два поля в каждой таблице содержимого, то есть createdBy и CreatedByGroup, и использую это в качестве точки, если у определенного пользователя есть разрешения. Но это недостаточно гибко, потому что для каждого нового контента, я должен пройти через все обновления данных и обновления разрешений. Пожалуйста, помогите мне, обсудив ваши лучшие практики для проектирования схемы.

Ответы [ 5 ]

34 голосов
/ 03 сентября 2014

Думаю, побитовый оператор - лучший способ реализовать права пользователя. Здесь я показываю, как мы можем реализовать это с 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).
Если у пользователя «Мехата» есть разрешение «Просмотр блога» (бит = 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');

Loding разрешение пользователя После входа в систему, если мы хотим загрузить разрешение пользователя, мы можем запросить разрешение ниже:

SELECT permission.bit,permission.name  
   FROM user LEFT JOIN permission ON user.role & permission.bit
 WHERE user.id = 1

Здесь user.role "&" allow.bit - побитовый оператор, который выдаст вывод как -

User-Add - 1
Blog-Delete - 64

Если мы хотим проверить погоду, у конкретного пользователя есть разрешение на редактирование или нет-

  SELECT * FROM `user` 
     WHERE role & (select bit from permission where name='user-edit')

Выходные данные = без строк.

Вы также можете увидеть: http://sforsuresh.in/implemention-of-user-permission-with-php-mysql-bitwise-operators/

34 голосов
/ 02 декабря 2008

Шаблон, который соответствует вашим потребностям, называется управление доступом на основе ролей .

Есть несколько хороших реализаций в PHP, включая Zend_Acl (хорошая документация), phpGACL и TinyACL . Большинство структур также имеют свои собственные реализации ACL в некоторой форме.

Даже если вы решите свернуть свои собственные, это поможет вам рассмотреть хорошо продуманные решения, подобные этим.

6 голосов
/ 03 декабря 2008

Возможно, вам не нужны группы разрешений. Вместо этого создайте группы пользователей, дайте разрешения группам пользователей и поместите пользователей в группы. Пользователи также должны иметь возможность переопределять разрешения для групп, в которых они находятся. Запретить всегда следует переопределять разрешение, если пользователь входит в более чем одну группу с разрешением.

В итоге:

  • Пользователь имеет ноль или более разрешений (нет, нет)
  • Пользователь в нулевой или нескольких группах
  • Группа имеет ноль или более разрешений (предоставить, запретить)
6 голосов
/ 02 декабря 2008

У меня была немного другая структура, но она должна быть справочной.

Каждый пользователь имеет ассоциированную с ним роль, идентификатор группы и таблицу групп, к которой относится идентификатор группы. Тогда у меня есть 3 таблицы разрешений.

PermissionMaster(FormName)

PermissionChild(PermissionMasterID, PermissionName, Desc, DefaultValue, DependOn) и

PermissionGroupChild(GroupID, PermissionChildID, Allow)

PermissionMaster содержит имя / форму / модуль, к которому относится разрешение. PermissionChild перечислит все возможные разрешения, доступные для каждого Мастера, такие как «Создать», «Вид», «Редактировать», «Удалить» и описание (у меня не было этого в первой версии, и это начало сбивать с толку когда слишком много настроек прав доступа даже для 1 модуля). Я разрешаю добавлять больше дочерних элементов, чтобы конкретно ссылаться на некоторую функцию, такую ​​как «ChangeTimeStamp», которая также давала бы более конкретное разрешение, чем «Редактировать»

Тогда PermissionGroupChild является связующим звеном между PermissionChild и таблицей группы. У каждой группы будет скопирован набор PermissionChild и задан параметр по умолчанию. Затем у меня был класс разрешений, который выполняет запрос и проверку таблиц для каждого пользователя. Я загружаю его только во время входа в систему. Затем в каждой форме / модуле я проверяю наличие соответствующих разрешений и правильно применяю пользовательский интерфейс.

Что касается роли, я использую ее только на странице конфигурации входа в систему. Меньшее значение роли означает более высокий рейтинг. Таким образом, пользователь может видеть только себя и тех, кто имеет значение Роль выше, чем он сам. Он / она может редактировать файлы более низкого ранга, чем он сам, но не похожи.

2 голосов
/ 18 сентября 2017

У меня есть группы и пользователи (например, решение 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 будет заполнять разрешения группы, поэтому у этого пользователя нет разрешения на добавление. Это побитовое говорит, что пользователь может только просматривать.

Он также работает с родительскими группами.

Что вы думаете об этом решении? У кого-нибудь есть лучший способ для этого?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...