Как я могу реализовать права форума - PullRequest
4 голосов
/ 30 мая 2010

Я начал разрабатывать приложение для форума на PHP на моей MVC Framework и перешел к этапу, когда я назначаю права доступа членам (например: READ, WRITE, UPDATE, DELETE).

Теперь я знаю, что могу добавить 5 столбцов под пользовательской таблицей в моей базе данных и установить для них 1 |0, но это кажется мне слишком большим, если я хочу добавить другие правила, например, MOVE.

И как я могу динамически назначать эти привилегии пользователям по отдельности?

I 'Вы слышали об использовании битовых масок, но было бы очень хорошо, если бы я мог полностью понять их, прежде чем продолжить.

У вас есть пример того, как я могу это реализовать?

Ответы [ 4 ]

4 голосов
/ 30 мая 2010

Битовая маска разрешений лучше всего понимается, когда она представлена ​​в двоичном виде, причем каждая цифра представляет разрешение, которое включено или выключено. Таким образом, если существуют разрешения X, Y и Z, и у меня есть доступ только к X и Z, 101 будет означать, что мне предоставлены первое и третье разрешения, но не второе. Двоичное число 101 эквивалентно десятичному числу 5, поэтому оно будет храниться в базе данных. Одно маленькое целое число - гораздо более эффективный объект для хранения, чем строка или несколько маленьких целых чисел.

РЕДАКТИРОВАТЬ: Я понял, насколько легко было использовать существующие функции преобразования, чтобы реализовать довольно быструю реализацию. Вот образец.

<?php
function bitmask_expand($n) {
  // 9 returns array(1, 0, 0, 1)
  return str_split(base_convert($n, 10, 2));
}

function bitmask_compact($a) {
  // array(1, 0, 0, 1) returns 9
  return (int) base_convert(implode($a), 2, 10);
}

$ns = range(0, 7);
foreach($ns as $n) {
  print_r($b = bitmask_expand($n));
  echo bitmask_compact($b), "\n\n";
}

Вы можете получить лучшую производительность, если будете использовать циклы, а не возвращаться к строкам и обратно, но это довольно четко иллюстрирует принцип.

3 голосов
/ 30 мая 2010

Метод, который вы описали - индивидуальные привилегии, хранящиеся в столбцах, - прост за счет гибкости (как вы заметили).

Метод Зуула еще более прост и по сути такой же, как у вас, за исключением того, что он избегает необходимости каких-либо операторов "ALTER TABLE". Однако он не нормализуется, не легко запрашивается и не самодокументируется.

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

Для форума маловероятно, что вам понадобится управление привилегиями для каждого пользователя. Скорее всего, у вас будут определенные классы пользователей, такие как анонимные пользователи, вошедшие в систему пользователи, модераторы, администраторы и т. Д. Это сделает его подходящим для управления доступом на основе ролей (RBAC). В этой системе вы назначаете каждому пользователю роль и предоставляете ей привилегии. Привилегии будут храниться в виде строк в таблице «привилегий». поэтому упрощенная схема базы данных будет выглядеть так:

PRIVILEGE
int id (primary key)
varchar description

ROLE_PRIVILEGE_JOIN
privilege_id (foreign key)
role_id (foreign key)

ROLE
int id (primary key)
varchar description

USER
int id (primary key)
int role_id (foreign key)

Этот шаблон используется во многих приложениях, которые имеют дело с привилегиями пользователя. Добавьте каждую привилегию, которую кто-либо может иметь в виде строки в таблице привилегий; добавить каждую роль, которую любой пользователь может иметь в таблице ролей; и связать их соответствующим образом в таблице role_privilege_join.

Единственный реальный недостаток заключается в том, что поскольку используется таблица соединения, запрос «может пользователь X сделать Y» будет несколько медленнее.

1 голос
/ 30 мая 2010

Я бы создал таблицу под названием «Роли»:

CREATE TABLE Roles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 rolename VARCHAR(30))

Вставьте туда все разрешения, которые хотите. Затем создайте таблицу под названием «UserRoles», чтобы связать пользователей с ролями:

CREATE TABLE UserRoles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 UserId INT,
 RoleID INT)

Много гибкости и простота сборки (т. Е. Рабочий процесс, правила и т. Д.) (Я бы тоже добавил внешние ключи)

0 голосов
/ 30 мая 2010

Вам не нужно усложнять это, просто используйте поле «ex: permissions» и сделайте что-то вроде:

$ permissions = "1; 1; 0; 1";

, где в вашем случае это гласит:

ЧИТАЙ - 1 (банка)

НАПИСАТЬ - 1 (банка)

ОБНОВЛЕНИЕ - 0 (не может)

УДАЛИТЬ - 1 (банка)

тогда, при проверке, просто используйте "explode" by ";" ...

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

Это обходной путь для вашей проблемы:)

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