Перейти к содержимому

Профиль пользователя на витрине - правка, свои поля, смена почты

Даём посетителю править свои данные: готовая форма профиля, свои поля учётной записи, смена пароля и безопасная смена почты с подтверждением.

Что нужно знать заранее

Правку своего профиля посетителю сайта даёт готовый штатный компонент платформы. Он же меняет пароль, показывает свои поля учётной записи и проверяет, что человек правит именно свою запись.

Смена адреса почты штатными средствами платформы никак не подтверждается отдельным письмом. Посетитель вписывает любой адрес, и письма о заказах начинают уходить туда, поэтому подтверждение делают своим кодом.

Свои поля учётной записи - это обычные пользовательские поля у сущности пользователя. Они заводятся один раз в настройках и дальше доступны и в профиле, и в коде.

Шаги

  1. Поставить компонент правки профиля на отдельную страницу личного раздела вашего сайта.
  2. Завести свои поля учётной записи и перечислить их в параметрах компонента.
  3. Разрешить смену пароля и проверить, как в этой форме работает политика паролей.
  4. Сделать подтверждение новой почты письмом со ссылкой и ограниченным сроком жизни.
  5. Проверить весь сценарий под обычным посетителем сайта, а не под администратором.

Решение

Ставим форму правки профиля:

$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); // ссылка одноразовая
}

Типичные проблемы

Посетитель поменял почту и перестал получать письма.

Новая почта записана без подтверждения, а в адресе была опечатка. Новый адрес подтверждают письмом со ссылкой и только потом записывают в учётную запись.

Свой контроллер правит чужой профиль.

Идентификатор пользователя берётся прямо из запроса и не сверяется с текущим. В любом своём коде правки сверяют идентификатор записи с идентификатором вошедшего человека.

Свои поля не появляются в форме профиля.

Поля заведены, но не перечислены в параметрах самого компонента правки профиля. Список полей задают явно: компонент не показывает все заведённые поля подряд.

Смена пароля не проходит без понятной причины.

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

После правки профиля посетителю приходит лишнее письмо.

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

Частые вопросы

Можно ли обойтись штатным компонентом профиля?

Для большинства сайтов да: он умеет свои поля, смену пароля и проверку прав. Свой контроллер пишут ради нестандартной вёрстки или пошаговой формы.

Как подтверждать новую почту?

Записать заявку с одноразовым кодом, отправить письмо со ссылкой и менять адрес только после перехода. Старый адрес до подтверждения остаётся рабочим.

Где хранить телефон и город?

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

Как сделать загрузку аватара?

Своим полем учётной записи типа «файл» с ограничением размера. Показывают уменьшенную копию, а исходник не отдают на витрину.

Нужно ли требовать старый пароль?

Да, при смене пароля из профиля это обычная практика. Без него доступ к чужой открытой сессии сразу даёт смену пароля.

Смежное

Первоисточник