#oop #design-patterns #architecture #user-permissions
#ооп #шаблоны проектирования #архитектура #пользователь-разрешения
Вопрос:
Я работаю над сайтом, на котором будет несколько модулей, которые либо полностью доступны определенным пользователям, либо полу доступны другим пользователям, либо недоступны остальным.
Например:
-
«Сотрудник» может отвечать на назначенные ему обращения в службу поддержки.
-
«Менеджер» может управлять всеми сотрудниками и поддерживать заявки в своей команде, включая просмотр заявок конкретного сотрудника.
-
«Администратор» способен управлять всеми менеджерами, сотрудниками и тикетами во всех командах, а также некоторыми другими основными функциональными возможностями.
Кроме того, на некоторых страницах будут отображаться некоторые дополнительные поля, если текущий пользователь является администратором или менеджером. (Например, ссылки на удаление / помечение объектов). Они не будут показаны сотрудникам.
Я хочу создать одну модель «Разрешений», которая будет обрабатывать логику для:
-
Определение того, может ли пользователь получить доступ к текущей странице или нет.
-
Определение того, должна ли отображаться определенная часть страницы или нет. (Например, специальные ссылки для редактирования / удаления, которые будут показаны только администраторам и менеджерам).
Мне нужны некоторые рекомендации / рекомендации по разработке этого класса, в частности, какие методы он должен иметь для выполнения второго требования.
Ответ №1:
Способ, которым я подошел к этой проблеме, когда она возникла, заключается в том, чтобы предоставить каждому действию, которое может быть предпринято, или фрагменту информации, который может быть показан, свое собственное Permission
. Затем у каждого User
есть коллекция Permissions
. Исходя из этого, вы можете добавить другие уровни структуры, чтобы помочь управлять огромным количеством существующих разрешений, таких как иерархии или категории разрешений.
Как только это будет установлено, вы можете либо попросить различные части запросить User
, есть ли у них необходимые разрешения, или вы можете PermissionManager
взять User
и набор Permissions
и определить, есть ли у данного пользователя необходимые Permissions
. Любой способ будет работать нормально, но то, какой из них вы выберете, влияет на зависимости и архитектуру вашей системы.
PermissionManager
Преимущество этого подхода в том, что части вашего приложения не должны зависеть от User
, поэтому вы могли бы использовать другой, PermissionManager
который всегда возвращает False
, если никакие разрешения не подходят, или True
если подходят все разрешения.
Для простых ситуаций этот подход может быть излишним, и поначалу часто кажется, что так оно и есть, но я пошел по пути использования базовых иерархических или крупнозернистых ролей, и мне нравится, что практически каждая система, над которой я работал, быстро становилась слишком сложной для большинства ванильных, готовых систем разрешений на основе ролей.
Комментарии:
1. @cdeszaaq Как / где должны храниться эти разрешения? Как они могут быть организованы в иерархии / категории? Кроме того, какие соглашения об именовании следует использовать для разрешений для их идентификации?
2. @Нажмите «Проголосовать» — Предполагая, что вы используете базу данных, все разрешения будут храниться там так же, как вы бы хранили любую другую структуру данных. Что касается соглашений об именовании, все, что имеет смысл, будет работать до тех пор, пока вы непротиворечивы, но я склонен придерживаться стиля «canDoX», где имена разрешений имеют какой-то глагол.
3. @нажмите «Проголосовать» хотя я предполагаю, что вы давно вышли за рамки, возможно, вам захочется исследовать RBAC
Ответ №2:
Мой подход к этой проблеме с точки зрения базы данных состоял бы в том, чтобы иметь таблицу пользователей, которая содержит список пользователей, таблицу ролей для списка ролей, например: сотрудник, менеджер, администратор; и таблицу разрешений, в которой хранятся все значения каждого действия / функции, доступной в системе, и ее разрешения для определенной роли, например: скажем, для администратора, все значения для действий / функций, таких как создание, редактирование, удаление, просмотр, являются истинными. Взаимосвязи можно увидеть ниже, тогда как (N) —- (N) — это отношение «многие ко многим».
Пользователи (N) ——- (N) Роли (N) ——— ( N) Разрешение
Ответ №3:
У меня сложилось впечатление, что вам потребуется использовать роли, например, сотрудника, менеджера и администратора. Итак, таблица ролей с этими данными подойдет. Тогда для конкретных действий / разрешений вам пришлось бы использовать логику ветвления, т. Е., например, для сотрудника, который у вас будет, если пользователь.IsInRole(«employee») // вставить логику для обработки обращений в службу поддержки клиентов else, если пользователь.IsInRole(«менеджер») // вставка логики для выполнения обязанностей менеджера
и, наконец, логика для решения обязанностей администратора
Итак, для достижения этого вам нужны как таблица users, так и таблица roles. Надеюсь, это поможет