2010-05-30 2 views
4

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

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

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

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

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

ответ

3

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

Метод Zuul является еще более простым и, по сути, таким же, как ваш, за исключением того, что он избегает необходимости в каких-либо утверждениях «ALTER TABLE». Тем не менее, это не нормируется, не легко запрашивается, а не самодокументируется.

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

Для форума маловероятно, что вам понадобится управление привилегиями для каждого пользователя. Скорее всего, у вас будут определенные классы пользователей, такие как анонимные пользователи, зарегистрированные пользователи, модераторы, администраторы и т. Д. Это сделает его подходящим для управления доступом на основе ролей (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.

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

+0

Хорошее описание на ловушках битмаски и магических струн. – itchi

+0

Спасибо за это, я думал о бит-масках, потому что его кое-что не удалось полностью справиться с этим, и я предположил, что должен точно знать, что это такое и как они работают, прежде чем я приму твердое решение о том, как будет работать система разрешений , но теперь вы помещаете его в контекст, так как нет необходимости в битовой маске, поскольку он просто создает простую задачу внутри приложения, плюс это позволяет легко сортировать, когда дело доходит до управления привилегиями в ACP. благодаря – RobertPitt

-1

Вам не нужно усложнять, что, просто используйте поле "Например:" разрешений и сделать что-то вроде:

$ разрешений = "1, 1, 0, 1";

где в вашей озабоченности гласит:

READ - 1 (может)

WRITE - 1 (может)

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

DELETE - 1 (может)

тогда, когда проверка, просто использовать "взорвется" от ";" ...

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

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

+1

Точки с запятой здесь кажутся ненужными, так как каждый бит разрешения - это всего лишь один символ. И когда вы собираетесь хранить строку двоичного кода, почему бы просто не сохранить ее как десятичную, а как ранее описанный принцип битмаски? – Matchu

+0

Да, ваше право! Это был пример, возможно, не самый лучший, но значение, разделенное символом «;» позволит вам в будущем добавлять разрешения, такие как 1; 0; 1; 1a; 0; <- (1a является «может» с уровнем «a»), но опять же вы можете использовать 12, где «2» будет субуровнем ... – Zuul

4

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

EDIT: Я понял, насколько легко было использовать существующие функции преобразования, чтобы получить довольно быструю реализацию. Вот пример.

<?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"; 
} 

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

1

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

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

Я думаю, что это немного перебор, чего хочет OP. Простая битовая маска будет делать. –

+0

Думаю, я должен был спросить о масштабах и размере своего приложения. PhpBB реализует аналогичную структуру с таблицами phpbb_user_group. http://www.phpbbdoctor.com/doc_tables.php – itchi

Смежные вопросы