Пользователи
Этот раздел про пользователей публичной части сайта — посетителей, которые регистрируются и логинятся в личный кабинет, оставляют заказы и т.п. Управление — раздел Пользователи (/cms/users) в админке.
Не путать с менеджерами
Менеджер (Manager) — сотрудник с доступом в админку. Управление — раздел Менеджеры (/cms/managers). См. Первый вход в админку.
Пользователь (User) — посетитель сайта. Управление — раздел Пользователи (/cms/users). Эта страница про него.
Разные таблицы (cms_users vs таблица менеджеров), разные guard'ы, разные API-эндпоинты.
Модель User
Класс: Templite\Cms\Models\User. Таблица: cms_users.
| Колонка | Назначение |
|---|---|
name | Имя пользователя |
email | Email (используется как login) |
password | Хэш пароля (Argon2/Bcrypt, автокаст hashed) |
user_type_id | FK на cms_user_types |
avatar_id | FK на files |
data | JSON — значения кастомных полей профиля |
settings | JSON — настройки пользователя (пользовательский UI и т.п.) |
is_active | Boolean — заблокирован/активен |
email_verified_at | Timestamp подтверждения email |
Дополнительно через trait/contracts:
MustVerifyEmail— поддержка подтверждения email.HasApiTokens(Sanctum) — Bearer-токены для API.
Aксессор avatar_url
$user->avatar_url;Возвращает:
/api/cms/media/serve/<id>— для аватара на локальном disk'е (проксируется через CMS, что позволяет проверять права).- Прямой URL — если файл на S3 / CDN.
null— если аватар не задан.
Кастомные поля профиля
Значения кастомных полей хранятся в JSON-колонке cms_users.data. Доступ:
$user->getFieldValue('bio', 'default value');
$user->setFieldValue('phone', '+7 999 000-00-00');
$user->save();Структура data определяется через UserField (см. ниже).
Типы пользователей (UserType)
Таблица cms_user_types. Каждый тип определяет сегмент аудитории с собственным guard'ом и набором разрешений.
| Колонка | Назначение |
|---|---|
slug | Идентификатор типа (customer, partner, member) |
name | Отображаемое название |
guard | Имя Laravel auth-guard'а — отделяет аутентификацию между типами |
module | Какой модуль владеет этим типом (для шопа, CRM и т.п.) |
permissions | JSON-массив разрешений |
settings | JSON: registration_enabled, email_verification_required и др. |
is_active | Boolean |
Multi-guard аутентификация
Templite поддерживает несколько guard'ов для разных сегментов пользователей. Например:
- Тип
customer(guardcustomer) — обычные клиенты сайта. - Тип
partner(guardpartner) — партнёрский личный кабинет.
Один и тот же email может быть зарегистрирован в обоих сегментах независимо — это реализуется через разные guard'ы.
Регистрация
Доступность регистрации настраивается per-type через settings:
$type->isRegistrationEnabled(); // settings.registration_enabled
$type->isEmailVerificationRequired(); // settings.email_verification_requiredЕсли регистрация выключена для типа — публичный endpoint регистрации возвращает 403.
Кастомные поля профиля (UserField)
Таблица cms_user_fields. Для каждого типа можно описать произвольные поля профиля.
| Колонка | Назначение |
|---|---|
user_type_id | FK на тип пользователя |
key | Идентификатор поля (snake_case) |
name | Отображаемое название |
type | Тип поля (см. ниже) |
default_value | Значение по умолчанию |
data | JSON-конфиг тип-специфичных опций |
hint | Подсказка для пользователя |
tab | Слаг таба в UI профиля |
parent_id | Вложенность (для repeater'ов) |
order | Порядок |
Допустимые типы полей
text, textfield, number, img, file, editor, tiptap, html,
select, checkbox, radio, link, date, datetime,
array, color, page, userЭто те же 18 типов, что у блоков, минус шопные (category, product, product_option). Подробнее — Поля.
Зарезервированные ключи
Имена полей не должны конфликтовать с колонками cms_users:
id, name, email, password, avatar, avatar_id,
type, user_type_id, settings, is_active, dataЗащита — UserField::RESERVED_KEYS.
Хранение значений
Значения кастомных полей хранятся в одной JSON-колонке cms_users.data — не в отдельной таблице values. Это отличает поведение от глобальных настроек и блоков:
| Сущность | Где хранятся значения полей |
|---|---|
| Блоки | page_blocks.data (JSON на странице) |
| Глобальные настройки | global_field_values (отдельная таблица) |
| Атрибуты страниц | page_attribute_values (отдельная таблица) |
| Профиль пользователя | cms_users.data (JSON в самой записи пользователя) |
Доступ — через $user->getFieldValue($key) / $user->setFieldValue($key, $value).
Аутентификация
Endpoint логина
POST /api/cms/user-auth/{guard}/login — отдельный endpoint для каждого guard'а.
Тело запроса:
{
"email": "user@example.com",
"password": "secret"
}Ответ (успех) — токен Sanctum:
{
"token": "1|abcdef...",
"user": { ... }
}Использование токена
Authorization: Bearer 1|abcdef...Текущий пользователь в Blade
В Blade-шаблонах публичной части можно использовать стандартные Laravel-фасады для guard'ов:
@auth('customer')
Привет, {{ auth('customer')->user()->name }}!
@endauth
@guest('customer')
<a href="/login">Войти</a>
@endguestВ контроллере:
$user = auth($guard)->user();Имя guard'а конкретного пользователя — $user->getGuardName().
2FA для frontend-пользователей
В отличие от менеджеров админки, для публичных пользователей 2FA из коробки не реализована. Если нужна — реализовать вручную через User->settings и middleware.
Программный доступ
Создание пользователя
use Templite\Cms\Models\User;
use Illuminate\Support\Facades\Hash;
$user = User::create([
'user_type_id' => $customerTypeId,
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'password' => 'secret123', // автокаст в hashed
'is_active' => true,
'data' => [
'phone' => '+7 999 000-00-00',
'city' => 'spb',
],
]);Так как password каст в hashed — Eloquent автоматически прогоняет значение через Hash::make().
Запрос по типу
User::whereHas('userType', fn ($q) => $q->where('slug', 'customer'))
->where('is_active', true)
->get();Управление через UI
В админке (/cms/users):
- Список пользователей с фильтрами по типу и активности.
- Создание/редактирование с заполнением кастомных полей профиля.
- Блокировка (
is_active = false).
В админке (/cms/users → раздел «Типы»):
- Управление UserType — slug, guard, permissions, настройки регистрации.
- Настройка кастомных полей (
UserField) для каждого типа.
Подводные камни
Подводные камни
- Это не менеджеры админки. Менеджеры — отдельная модель в другой таблице. Сброс пароля менеджера —
cms:reset-password <login>, для frontend-пользователей такой команды нет. - Таблица
cms_users, неusers. Если в проекте уже есть стандартная Laravel-таблицаusers— она остаётся независимой. CMS не использует её для frontend-пользователей. - Multi-guard. Один email может быть зарегистрирован в разных guard'ах одновременно. Поэтому unique-индекс на email — обычно в рамках guard'а, не глобальный.
- Зарезервированные ключи кастомных полей нельзя использовать. Они перекрывают колонки модели.
- Значения кастомных полей хранятся в JSON-колонке
data, не в отдельной таблице. Это упрощает CRUD, но делает запросы по значениям полей менее эффективными — для частых запросов добавляйте отдельные индексированные колонки. avatar_urlдля локальных файлов проксируется через/api/cms/media/serve/<id>, не отдаёт прямой Storage-URL. Это позволяет проверять права (приватные аватары и т.п.). Для S3/CDN аватаров — прямой URL.- 2FA для frontend-пользователей не реализована в CMS. Только для менеджеров админки.
- При смене
APP_KEYSanctum-токены становятся недействительными (как и сессии). Все пользователи и менеджеры будут разлогинены.
Связанные разделы
- Первый вход в админку — про менеджеров (
Manager) - REST API — Sanctum-аутентификация и
/api/cms/user-auth/{guard}/login - Поля — типы для UserField
- Файлы и медиа — аватары
- Локализация и города — guard'ы и языковая сегментация