Почему нужна авторизация через SMS без пароля
Традиционная авторизация с паролем часто вызывает сложности у пользователей: забытые пароли, слабая безопасность, необходимость частой смены пароля. Авторизация через SMS-код (one-time password, OTP) упрощает вход и повышает удобство без снижения безопасности. WPForms в связке с кастомным кодом позволяет реализовать такой механизм без использования дополнительных крупных плагинов.
Диагностика задачи: что нужно учесть при реализации
- Наличие поля для ввода номера телефона в форме.
- Генерация и отправка одноразового кода через SMS.
- Временное хранение кода и проверка при вводе пользователем.
- Создание или поиск пользователя по номеру телефона.
- Вход пользователя в систему по успешной валидации кода.
- Обработка ошибок и ограничение попыток ввода кода.
Требования к SMS-оператору
Для отправки SMS потребуется интеграция с SMS-шлюзом (например, Twilio, Nexmo, или любой локальный оператор с API). В статье приведён пример с использованием Twilio PHP SDK.
Пошаговое решение: настройка формы и обработка авторизации
1. Создаём форму с полем для телефона и ввода кода
В WPForms создайте форму с двумя полями:
- Телефон (Phone)
- Код подтверждения (Single Line Text)
Изначально поле «Код подтверждения» должно быть скрыто, чтобы показать его после отправки номера.
2. Отправка SMS с кодом через AJAX
Добавьте JavaScript для отправки номера телефона на сервер и получения SMS-кода:
jQuery(document).ready(function($) {
$('#wpforms-form-123').on('submit', function(e) {
e.preventDefault();
var phone = $('#wpforms-123-field_1').val();
if (!phone) {
alert('Введите номер телефона');
return;
}
$.ajax({
url: wpforms_ajax_object.ajax_url,
method: 'POST',
data: {
action: 'send_sms_code',
phone: phone,
security: wpforms_ajax_object.nonce
},
success: function(response) {
if(response.success) {
$('#wpforms-123-field_2-container').show();
alert('Код отправлен на номер ' + phone);
} else {
alert('Ошибка: ' + response.data);
}
}
});
});
});3. Обработка AJAX-запроса и отправка SMS
Добавьте следующий PHP код в functions.php вашей темы или в плагин:
use Twilio\Rest\Client;
add_action('wp_ajax_send_sms_code', 'send_sms_code_callback');
add_action('wp_ajax_nopriv_send_sms_code', 'send_sms_code_callback');
function send_sms_code_callback() {
check_ajax_referer('wpforms_nonce', 'security');
$phone = sanitize_text_field($_POST['phone']);
if (!preg_match('/^\+\d{10,15}$/', $phone)) {
wp_send_json_error('Неверный формат номера телефона');
}
$code = rand(100000, 999999);
$expires = time() + 300; // код действителен 5 минут
// Сохраняем код и время в сессии
if (!session_id()) session_start();
$_SESSION['sms_auth_code'] = $code;
$_SESSION['sms_auth_phone'] = $phone;
$_SESSION['sms_auth_expires'] = $expires;
// Отправка SMS через Twilio
$sid = 'TWILIO_SID';
$token = 'TWILIO_TOKEN';
$twilio_number = '+1234567890';
try {
$client = new Client($sid, $token);
$message = $client->messages->create(
$phone,
['from' => $twilio_number, 'body' => "Ваш код для входа: $code"]
);
wp_send_json_success();
} catch (Exception $e) {
wp_send_json_error('Не удалось отправить SMS: ' . $e->getMessage());
}
}4. Проверка кода и авторизация пользователя
Добавьте обработчик отправки формы в WPForms:
add_action('wpforms_process_complete', 'check_sms_code_and_auth', 10, 4);
function check_sms_code_and_auth($fields, $entry, $form_data, $entry_id) {
if ($form_data['id'] != 123) return; // ID вашей формы
if (!session_id()) session_start();
$input_code = '';
$input_phone = '';
foreach ($fields as $field) {
if ($field['id'] == 2) $input_code = $field['value'];
if ($field['id'] == 1) $input_phone = $field['value'];
}
if (empty($_SESSION['sms_auth_code']) || empty($_SESSION['sms_auth_phone'])) {
wpforms()->process->errors[$form_data['id']][0] = 'Сначала запросите код на телефон';
return;
}
if ($_SESSION['sms_auth_expires'] < time()) {
wpforms()->process->errors[$form_data['id']][0] = 'Время действия кода истекло';
return;
}
if ($input_code != $_SESSION['sms_auth_code'] || $input_phone != $_SESSION['sms_auth_phone']) {
wpforms()->process->errors[$form_data['id']][0] = 'Неверный код или номер телефона';
return;
}
// Поиск пользователя по номеру телефона
$user = get_users(array(
'meta_key' => 'phone',
'meta_value' => $input_phone,
'number' => 1
));
if (empty($user)) {
// Если пользователь не найден, создаём нового
$userdata = array(
'user_login' => 'user_' . sanitize_text_field(preg_replace('/\D+/', '', $input_phone)),
'user_pass' => wp_generate_password(),
'meta_input' => array('phone' => $input_phone),
);
$user_id = wp_insert_user($userdata);
if (is_wp_error($user_id)) {
wpforms()->process->errors[$form_data['id']][0] = 'Ошибка создания пользователя';
return;
}
$user = get_user_by('id', $user_id);
} else {
$user = $user[0];
}
// Авторизация пользователя
wp_clear_auth_cookie();
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID);
// Очищаем сессию
unset($_SESSION['sms_auth_code']);
unset($_SESSION['sms_auth_phone']);
unset($_SESSION['sms_auth_expires']);
// Перенаправление после успешного входа
wp_redirect(home_url());
exit;
}Проверка результата после внедрения
- Откройте форму, введите номер телефона в международном формате (например, +79161234567).
- Нажмите отправить — должно появиться сообщение об отправке SMS и появиться поле для ввода кода.
- Введите полученный SMS-код и отправьте форму повторно.
- Проверьте, что пользователь авторизован (появился доступ к приватным страницам, отображается имя пользователя).
- Если пользователь новый — проверьте, что он создан в админке WordPress с мета-данными телефона.
Частые ошибки и как их исправить
- Неверный формат номера телефона: убедитесь, что номер вводится в формате +кодстраны и только цифры, без пробелов и скобок.
- Не приходит SMS: проверьте настройки и креденшалы SMS-провайдера, баланс на счету, правильность номера отправителя.
- Код не совпадает или срок действия истёк: проверьте работу сессий, возможно, PHP сессии не стартуют, добавьте
session_start()в начале файла. - Пользователь не создаётся: проверьте права на создание пользователей, корректность данных, наличие ошибок в логах.
- Редирект не срабатывает после авторизации: убедитесь, что нет вывода до вызова
wp_redirect()и что скрипт завершаетсяexit;.
Практические советы по безопасности и производительности
- Ограничьте количество запросов на отправку SMS с одного IP или одного телефона, чтобы избежать спама и перегрузки.
- Храните коды только во временной сессии, не сохраняйте в базе данных без необходимости.
- Используйте защищённое соединение HTTPS для передачи данных формы и AJAX-запросов.
- Регулярно обновляйте SDK и плагины, связанные с SMS-провайдером, для защиты от уязвимостей.
- Для снижения нагрузки кэшируйте страницу с формой и отключайте кэш для AJAX-запросов авторизации.
Сравнение вариантов реализации авторизации через SMS
| Вариант | Описание | Преимущества | Недостатки |
|---|---|---|---|
| WPForms + кастомный код + Twilio | Гибкая кастомизация, контроль над логикой | Полный контроль, интеграция с существующими формами | Требуется программирование, настройка SMS API |
| Плагины авторизации SMS (например, miniOrange) | Готовые решения с настройками | Быстрая установка, поддержка | Могут быть платными, ограниченная кастомизация |
| Сторонние сервисы с виджетами | Интеграция через iframe или скрипты | Простота, внешняя поддержка безопасности | Зависимость от внешних сервисов, ограниченный дизайн |