В этой главе подробно рассматривается устройство подсистемы пользователей, архитектура разграничения прав доступа (ACL) и механизмы безопасности в Seditio CMS. Вы узнаете, как распределяются роли пользователей, как устроена битовая маска прав доступа, как кэшируются права в базе данных, а также принципы авторизации и шифрования.
4.1. Группы пользователей и системные роли
Система управления доступом в Seditio построена на ролевой модели. Все зарегистрированные пользователи обязательно состоят в группах.
4.1.1. Системные (зарезервированные) группы пользователей
В Seditio по умолчанию присутствуют предопределенные группы с зарезервированными идентификаторами (ID), которые жестко завязаны на внутреннюю логику ядра:
- Guests (Гости / ID = 1): Неавторизованные посетители сайта. Группа определяет, к какому контенту и функционалу сайта есть публичный доступ.
- Inactive (Неактивные / ID = 2): Пользователи, прошедшие регистрацию, но ожидающие активации аккаунта (например, по ссылке из e-mail или после проверки администратором).
- Banned (Заблокированные / ID = 3): Пользователи, аккаунты которых временно или навсегда заблокированы.
- Members (Участники / ID = 4): Стандартная группа для всех успешно зарегистрированных и активированных пользователей сайта.
- Team members (Администраторы / ID = 5): Члены команды с полными административными правами. Пользователи этой группы имеют доступ в панель управления (
/adminилиindex.php?module=adminбез ЧПУ) по умолчанию. - Moderators (Модераторы / ID = 6): Группа пользователей с модераторскими привилегиями на форумах и в категориях страниц.
4.1.2. Концепция основной группы и дополнительных групп
У каждого пользователя в Seditio есть две плоскости принадлежности к группам:
- Основная группа (
user_maingrp): Хранится в таблице пользователейsed_users. Она определяет базовую роль пользователя на сайте, его скин по умолчанию, язык интерфейса и уровень доступа. - Дополнительные группы (Таблица
sed_groups_users): Пользователь может состоять в неограниченном числе дополнительных групп. Принадлежность связывается через таблицу отношенийsed_groups_users(колонкиgru_useridиgru_groupid).
При проверке прав доступа ядро Seditio объединяет привилегии основной группы пользователя и всех дополнительных групп, в которых он состоит.
4.2. Архитектура и битовая маска ACL (Access Control List)
Вся матрица прав доступа в Seditio CMS хранится в таблице sed_auth. Запись о правах привязывается к группе пользователей (auth_groupid), области системы (auth_code — например, page, forums, admin) и конкретной опции внутри этой области (auth_option — например, категория страниц или раздел форума).
4.2.1. Байт как битовая маска прав доступа
Для минимизации размера базы данных и максимальной производительности права на конкретное действие хранятся в виде 8-битного целого числа (один байт от 0 до 255), где каждый бит отвечает за определенное разрешение:
- Бит 0 (вес 1):
Read(Чтение /R). Разрешает просмотр контента. - Бит 1 (вес 2):
Write(Запись /W). Разрешает добавление и редактирование собственного контента. - Бит 2 (вес 4): Пользовательское разрешение 1 (
1). - Бит 3 (вес 8): Пользовательское разрешение 2 (
2). - Бит 4 (вес 16): Пользовательское разрешение 3 (
3). - Бит 5 (вес 32): Пользовательское разрешение 4 (
4). - Бит 6 (вес 64): Пользовательское разрешение 5 (
5). - Бит 7 (вес 128):
Admin(Администрирование /A). Разрешает модерирование, удаление чужого контента и управление настройками раздела.
Таким образом, если группа имеет полные права на раздел (Чтение + Запись + Администрирование), значение её прав в БД будет равно 1 + 2 + 128 = 131.
4.2.2. Наследование и кумулятивное сложение прав
Если пользователь состоит в нескольких группах одновременно, система не перезаписывает права одной группы правами другой, а применяет принцип кумулятивного сложения (побитового ИЛИ).
При авторизации пользователя функция sed_auth_build() запрашивает права для всех групп, в которых состоит пользователь, и собирает их в единую сетку прав с использованием побитового оператора ИЛИ (|=):
// Cumulative bitwise OR merging of user rights from multiple groups @$authgrid[$row['auth_code']][$row['auth_option']] |= $row['auth_rights'];
Пример:
- Пользователь состоит в группе Members, у которой права на чтение форума равны
1(только Чтение). - Этот же пользователь состоит в дополнительной группе Moderators, у которой права на этот же форум равны
128(Администрирование). - Итоговые права пользователя составят
1 | 128 = 129(Чтение + Администрирование).
4.3. Процесс проверки авторизации в коде (sed_auth)
Ядро системы использует встроенные функции для построения и проверки сетки прав.
4.3.1. Сборка сетки прав при входе пользователя
При успешной авторизации или при первом обращении к странице вызывается функция sed_auth_build(). Она сканирует все группы пользователя, выполняет SQL-запрос к таблице sed_auth и строит двумерный ассоциативный массив вида:
$usr['auth'][$area][$option] = $bitwise_rights;
4.3.2. Проверка доступа в коде
Для проверки наличия прав в PHP-скриптах используется ключевая функция sed_auth(). Она принимает три параметра:
$area(string) — защищаемая область (например,'page','forums','admin').$option(string) — конкретный подраздел или категория (например,'news'для категории страниц).$mask(string) — строка проверяемых масок (по умолчанию'RWA').
Функция сопоставляет битовую маску запрашиваемых прав с правами текущего пользователя и возвращает TRUE или FALSE.
Пример проверки прав в коде:
// Check if user has both Read ® and Write (W) permissions for 'page' module, category 'news'
list($usr['auth_read'], $usr['auth_write'], $usr['isadmin']) = sed_auth('page', 'news', 'RWA');
if (!$usr['auth_read']) {
// Redirect or show error if no read rights
sed_die();
}
4.3.3. Оптимизация производительности: кэширование прав
Для того чтобы избежать выполнения ресурсоемких SQL-запросов и побитового объединения массивов прав при каждом клике пользователя, Seditio CMS кэширует готовую сетку прав авторизованного пользователя:
- В таблице
sed_usersпредусмотрено полеuser_authтипаTEXT. - При первой сборке прав результат работы
sed_auth_build()сериализуется черезserialize()и сохраняется в это поле. - При каждом последующем обращении к страницам права пользователя мгновенно загружаются из базы данных одной строкой и десериализуются:
$usr['auth'] = unserialize($row['user_auth']);. - Сброс кэша: При изменении прав групп в админке или добавлении пользователей в новые группы система принудительно сбрасывает кэш прав всех пользователей (
UPDATE sed_users SET user_auth=''), что заставит ядро перегенерировать сетку прав при их следующем заходе на сайт.
4.4. Профиль пользователя и механизм его расширения
Каждый пользователь имеет индивидуальную карточку профиля, данные которой хранятся в таблице sed_users.
4.4.1. Системная структура профиля
В состав профиля по умолчанию входят следующие ключевые поля:
user_id— уникальный идентификатор пользователя.user_name— логин (уникальное имя для авторизации).user_passwordиuser_salt— хэш пароля и соль.user_maingrp— основная группа пользователя.user_email— адрес электронной почты.user_avatarиuser_photo— аватар и фотография.user_timezone,user_lang,user_skin— региональные настройки (часовой пояс, язык, тема оформления).user_regdate,user_lastlog,user_lastip— статистика активности.
4.4.2. Расширение профиля с помощью словарей
Если стандартных полей профиля недостаточно (например, требуется добавить поля «Номер телефона», «Адрес доставки» или «Telegram ID»), администратор может расширить профиль без изменения исходного PHP-кода:
- В разделе «Словари» по адресу
/admin/dic(илиindex.php?module=admin&m=dicбез ЧПУ) создается новый словарь. - Целевой таблицей выбирается таблица пользователей
users. - Создаются элементы словаря (
sed_dic/sed_dic_items). - Система выполняет SQL-запрос
ALTER TABLE sed_users ADD user_field_name ..., физически расширяя структуру базы данных. - Новое поле автоматически интегрируется в форму редактирования профиля в кабинете пользователя, в панель администрирования и становится доступно в TPL-шаблонах через теги вида
{USER_FIELD_NAME}.
4.5. Механизм сессий, авторизации и безопасности
Безопасность авторизации пользователей обеспечивается комплексом мер на уровне сессий, кук и криптографического хэширования.
4.5.1. Схема авторизации и Persistent Login
В Seditio поддерживается три режима авторизации (задаются через конфигурацию $cfg['authmode']):
- Только сессии (режим 1): Авторизация привязана к сессии PHP.
- Только куки (режим 2): Персистентный вход.
- Смешанный режим (режим 3): Используются и куки, и сессии.
При персистентном входе авторизация базируется на специальной куке автологина с именем $sys['site_id']:
- Данные в куке хранятся в зашифрованном
base64виде и имеют структуру:user_id:_:user_secret:_:user_skin. - При каждом запросе ядро считывает куку, декодирует её и сопоставляет поля с базой данных:
// Decoding persistent login cookie value $u = base64_decode($_COOKIE[$sys['site_id']]); $u = explode(':_:', $u); $rsedition = $u[0]; // User ID $rseditiop = $u[1]; // User Secret hash - Если включена проверка по IP (
$cfg['ipcheck']), ядро дополнительно проверяет совпадение текущего IP-адреса пользователя с IP-адресом его последнего входа (user_lastip), что защищает от перехвата сессии/куки.
4.5.2. Хэширование паролей и использование Site Secret
Для защиты паролей от компрометации в случае утечки базы данных в Seditio используется двухфакторное хэширование с солью:
- При регистрации для пользователя генерируется уникальная случайная соль (
user_salt). - Хэш пароля генерируется функцией sed_hash() с использованием глобального секретного ключа сайта
$cfg['site_secret'](задается в файлеdatas/config.phpпри установке):// Hashing logic using user salt and unique site secret key $res = hash($algorithm, hash($algorithm, $password) . $cfg['site_secret'] . $salt);
- Двойное обертывание алгоритмом хэширования (
md5по умолчанию) и уникальная соль для каждого пользователя защищают пароли от взлома по радужным таблицам (Rainbow Tables).
4.5.3. Защита от брутфорса и Бан-лист
- Аудит неудачных попыток входа: В системе ведется журнал логирования. Все неудачные попытки авторизации под любым именем записываются в лог безопасности (
sec), включая IP-адрес нападающего. - Блокировки по IP и e-mail (Бан-лист): В панели управления по адресу
/admin/banlist(илиindex.php?module=admin&m=banlistбез ЧПУ) администратор может блокировать доступ к сайту по конкретному IP, маске подсети (например,192.168.1.*) или по e-mail маске (например,*@spamdomain.com). При обращении к любой странице ядро Seditio сверяет IP посетителя с бан-листом и при совпадении немедленно прекращает выполнение скрипта.
Comments: (0)