Проблема: стандартная регистрация и вход WooCommerce не поддерживают авторизацию по телефону
WooCommerce из коробки использует email и пароль для авторизации пользователей. В некоторых нишах удобнее и безопаснее подключить авторизацию через телефон и One-Time Password (OTP) по SMS. Это уменьшит количество забытых паролей, повысит конверсию регистрации и упростит UX.
Диагностика задачи: что нужно и какие инструменты
Задача — заменить или дополнить стандартную форму входа WooCommerce возможностью войти по номеру телефона и коду из SMS без пароля.
- Проверить, есть ли на сайте подключение к SMS-шлюзу (Twilio, SMS.RU, или другой).
- Подготовить кастомную форму входа с полем для телефона и кнопкой запроса OTP.
- Обработать ввод OTP и логин пользователя.
- Обеспечить привязку номера телефона к профилю пользователя WooCommerce.
Пошаговое решение: реализация авторизации через телефон с OTP
1. Добавляем поле телефон в профиль пользователя WooCommerce
Используем хук show_user_profile и edit_user_profile_update для сохранения телефона:
add_action('show_user_profile', 'add_phone_field_to_profile');
add_action('edit_user_profile', 'add_phone_field_to_profile');
function add_phone_field_to_profile($user) {
?>
<h3>Телефон для авторизации</h3>
<table class="form-table">
<tr>
<th><label for="phone">Телефон</label></th>
<td>
<input type="text" name="phone" id="phone" value="<?php echo esc_attr(get_user_meta($user->ID, 'phone', true)); ?>" class="regular-text" />
</td>
</tr>
</table>
<?php
}
add_action('personal_options_update', 'save_phone_field');
add_action('edit_user_profile_update', 'save_phone_field');
function save_phone_field($user_id) {
if (!current_user_can('edit_user', $user_id)) {
return false;
}
update_user_meta($user_id, 'phone', sanitize_text_field($_POST['phone']));
}2. Создаем кастомную форму входа с номером телефона и запросом OTP
Добавим шорткод для вывода формы:
function phone_login_form_shortcode() {
ob_start();
?>
<form id="phone-login-form" method="post">
<input type="text" name="phone" id="phone" placeholder="Введите номер телефона" required />
<button type="button" id="send-otp">Отправить код</button>
<div id="otp-container" style="display:none;">
<input type="text" name="otp" id="otp" placeholder="Введите код из SMS" required />
<button type="submit">Войти</button>
</div>
</form>
<script>
document.getElementById('send-otp').addEventListener('click', function() {
var phone = document.getElementById('phone').value.trim();
if(!phone) {
alert('Введите номер телефона');
return;
}
fetch('<?php echo admin_url('admin-ajax.php'); ?>?action=send_otp&phone=' + encodeURIComponent(phone))
.then(response => response.json())
.then(data => {
if(data.success) {
alert('Код отправлен');
document.getElementById('otp-container').style.display = 'block';
} else {
alert(data.data);
}
});
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('phone_login_form', 'phone_login_form_shortcode');3. Обработка AJAX запроса для отправки SMS с OTP
Для примера используем сессию для хранения кода. В реальном проекте подключайте SMS-шлюз.
add_action('wp_ajax_send_otp', 'send_otp_callback');
add_action('wp_ajax_nopriv_send_otp', 'send_otp_callback');
function send_otp_callback() {
if (!isset($_GET['phone'])) {
wp_send_json_error('Номер телефона не передан');
}
$phone = sanitize_text_field($_GET['phone']);
// Генерируем случайный 6-значный код
$otp = rand(100000, 999999);
// Здесь отправка SMS через API SMS-шлюза
// Для примера просто сохраняем в сессию
if(!session_id()) session_start();
$_SESSION['otp_for_' . $phone] = $otp;
// debug
error_log("Отправлен OTP для $phone: $otp");
wp_send_json_success();
}4. Обработка формы входа и проверка OTP
Логиним пользователя по номеру телефона, если OTP совпадает:
add_action('init', function() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['phone'], $_POST['otp'])) {
$phone = sanitize_text_field($_POST['phone']);
$otp = sanitize_text_field($_POST['otp']);
if(!session_id()) session_start();
$stored_otp = $_SESSION['otp_for_' . $phone] ?? '';
if ($otp === $stored_otp) {
// Ищем пользователя по мета-полю phone
$user_query = new WP_User_Query(array(
'meta_key' => 'phone',
'meta_value' => $phone,
'number' => 1
));
$users = $user_query->get_results();
if (!empty($users)) {
wp_set_current_user($users[0]->ID);
wp_set_auth_cookie($users[0]->ID);
unset($_SESSION['otp_for_' . $phone]);
wp_redirect(home_url());
exit;
} else {
echo '<p>Пользователь с таким номером не найден.</p>';
}
} else {
echo '<p>Неверный код.</p>';
}
}
});Проверка результата после внедрения
- Перейдите на страницу с шорткодом
[phone_login_form]. - Введите номер телефона, который сохранён в профиле пользователя.
- Нажмите «Отправить код» — в логи сервера должен попасть сгенерированный OTP.
- Введите OTP из лога и нажмите «Войти».
- Проверьте, что пользователь авторизовался и перешёл на главную.
Частые ошибки и как исправить
- OTP не отправляется или приходит с задержкой — проверьте интеграцию с SMS-шлюзом, правильность API-ключей и лимиты отправки.
- Номер телефона не сохраняется в профиле — убедитесь, что поля формы и обработчики сохранения корректно работают.
- Пользователь не найден по номеру телефона — проверьте, что телефон сохранён в метаполе
phoneи формат совпадает. - Авторизация не происходит — проверьте, вызывается ли
wp_set_auth_cookie()и нет ли редиректов после логина.
Практические советы по безопасности и производительности
- Хранить OTP в сессии — простой способ, но для масштабируемых сайтов лучше использовать transient API или отдельную таблицу с временем жизни кода.
- Ограничьте количество попыток ввода OTP с одного номера, чтобы защититься от перебора.
- Используйте HTTPS для защиты передачи данных формы.
- При интеграции с SMS-шлюзом используйте проверенные, надёжные сервисы с гарантированной доставкой.
Сравнение вариантов реализации авторизации по телефону в WooCommerce
| Решение | Плюсы | Минусы |
|---|---|---|
| Кастомный код (как в статье) | Полный контроль, лёгкость кастомизации | Требуется разработка SMS-интеграции, поддержка |
| Плагины авторизации по телефону (например, "WP SMS Login") | Быстрая установка, готовая интеграция с SMS-сервисами | Может быть платным, ограниченная кастомизация |
| Использование сторонних сервисов OAuth или Social Login | Удобство, поддержка нескольких провайдеров | Зависимость от сторонних сервисов, не всегда телефон |