Подтвердить что ты не робот

Лучшая практика для разработки роли пользователя и системы разрешений?

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

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

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

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

4b9b3361

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

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

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