Профиль пользователя на витрине - правка, свои поля, смена почты
Даём посетителю править свои данные: готовая форма профиля, свои поля учётной записи, смена пароля и безопасная смена почты с подтверждением.
Что нужно знать заранее
Правку своего профиля посетителю сайта даёт готовый штатный компонент платформы. Он же меняет пароль, показывает свои поля учётной записи и проверяет, что человек правит именно свою запись.
Смена адреса почты штатными средствами платформы никак не подтверждается отдельным письмом. Посетитель вписывает любой адрес, и письма о заказах начинают уходить туда, поэтому подтверждение делают своим кодом.
Свои поля учётной записи - это обычные пользовательские поля у сущности пользователя. Они заводятся один раз в настройках и дальше доступны и в профиле, и в коде.
Шаги
- Поставить компонент правки профиля на отдельную страницу личного раздела вашего сайта.
- Завести свои поля учётной записи и перечислить их в параметрах компонента.
- Разрешить смену пароля и проверить, как в этой форме работает политика паролей.
- Сделать подтверждение новой почты письмом со ссылкой и ограниченным сроком жизни.
- Проверить весь сценарий под обычным посетителем сайта, а не под администратором.
Решение
Ставим форму правки профиля:
$APPLICATION->IncludeComponent('bitrix:main.profile', '', [ 'SET_TITLE' => 'Y', 'USER_PROPERTY' => ['UF_PHONE', 'UF_CITY'], // свои поля учётной записи 'USER_PROPERTY_NAME' => 'Дополнительно', 'SEND_INFO' => 'N', // письмо о правке профиля]);Компонент сам проверяет, что человек правит свою запись. Подменить идентификатор в запросе не выйдет: он берёт текущего пользователя, а не значение из адресной строки.
Смотрим, какие свои поля заведены:
$fields = $USER_FIELD_MANAGER->GetUserFields('USER', $USER->GetID(), LANGUAGE_ID);foreach ($fields as $code => $field) { printf("%-14s %-10s значение=%s\n", $code, $field['USER_TYPE_ID'], is_array($field['VALUE']) ? implode(',', $field['VALUE']) : $field['VALUE']);}Правим профиль из кода:
$cuser = new \CUser();if ((int)$id !== (int)$USER->GetID() && !$USER->IsAdmin()) { return; } // чужое не трогаемif (!$cuser->Update($id, ['NAME' => $name, 'UF_CITY' => $city])) { echo $cuser->LAST_ERROR;}Проверка «своя ли это запись» обязательна в любом своём коде правки. Компонент её делает сам, а собственный контроллер о ней часто забывают, и правка чужого профиля становится вопросом одного запроса.
Подтверждаем новую почту письмом:
$token = bin2hex(random_bytes(16));$store = \Bitrix\Main\Application::getInstance()->getManagedCache();$store->setImmediate('email_confirm_' . $token, ['id' => $id, 'email' => $newEmail]);\CEvent::Send('VENDOR_EMAIL_CONFIRM', SITE_ID, ['EMAIL' => $newEmail, 'LINK' => 'https://example.com/confirm/?t=' . $token]);Пока подтверждение не пришло, почта в учётной записи остаётся прежней. Иначе опечатка в адресе отрезает человека и от восстановления пароля, и от писем о его заказах.
Записываем почту после перехода по ссылке:
$data = $store->read(86400, 'email_confirm_' . $token) ? $store->get() : null;if ($data) { (new \CUser())->Update($data['id'], ['EMAIL' => $data['email']]); $store->clean('email_confirm_' . $token); // ссылка одноразовая}Типичные проблемы
Посетитель поменял почту и перестал получать письма.
Новая почта записана без подтверждения, а в адресе была опечатка. Новый адрес подтверждают письмом со ссылкой и только потом записывают в учётную запись.
Свой контроллер правит чужой профиль.
Идентификатор пользователя берётся прямо из запроса и не сверяется с текущим. В любом своём коде правки сверяют идентификатор записи с идентификатором вошедшего человека.
Свои поля не появляются в форме профиля.
Поля заведены, но не перечислены в параметрах самого компонента правки профиля. Список полей задают явно: компонент не показывает все заведённые поля подряд.
Смена пароля не проходит без понятной причины.
Новый пароль не удовлетворяет требованиям политики паролей у групп этого пользователя. Требования политики показывают рядом с полем, а не оставляют человека гадать.
После правки профиля посетителю приходит лишнее письмо.
В параметрах компонента включено письмо-уведомление о каждом изменении любых данных профиля. Письмо-уведомление посетителю оставляют только для смены пароля и смены адреса почты.
Частые вопросы
Можно ли обойтись штатным компонентом профиля?
Для большинства сайтов да: он умеет свои поля, смену пароля и проверку прав. Свой контроллер пишут ради нестандартной вёрстки или пошаговой формы.
Как подтверждать новую почту?
Записать заявку с одноразовым кодом, отправить письмо со ссылкой и менять адрес только после перехода. Старый адрес до подтверждения остаётся рабочим.
Где хранить телефон и город?
В своих полях учётной записи: они доступны и в профиле, и в коде, и в выгрузках. Отдельная таблица нужна, только если данных много и они меняются часто.
Как сделать загрузку аватара?
Своим полем учётной записи типа «файл» с ограничением размера. Показывают уменьшенную копию, а исходник не отдают на витрину.
Нужно ли требовать старый пароль?
Да, при смене пароля из профиля это обычная практика. Без него доступ к чужой открытой сессии сразу даёт смену пароля.
Смежное
- Авторизация и сессии - оглавление подтемы
- Регистрация покупателей: форма, подтверждение, свои поля - откуда берутся эти поля
- Страница и форма авторизации: компоненты, шаблоны, возврат после входа - соседние компоненты личного раздела
- Не работает восстановление пароля: причины по убыванию частоты - что ломается при неверной почте
- Пользовательские поля у своей сущности: регистрация, запись, чтение - устройство своих полей
- Личный кабинет покупателя: список заказов, повтор и отмена - соседние страницы кабинета
- Согласие на обработку данных: соглашение, компонент, запись факта - согласие при правке данных
- Пользователи, группы и права доступа - устройство учётных записей целиком