Подтверждение email для новых пользователей
Я хочу реализовать плагин, который будет требовать от новых пользователей подтверждения email путем ответа на письмо при регистрации. Я уже активно изучаю документацию, но я новичок и был бы признателен за подсказки, особенно касательно того, как оставить пользователя неактивным до подтверждения email. Остальное, думаю, смогу сделать сам.
У меня была очень похожая проблема, которую я решил на днях. В моем случае я хотел позволить пользователям выбирать свой пароль, а затем активировать учетную запись через email. Здесь много нюансов, поэтому я просто кратко опишу, как реализовал проверку по email.
Сначала я использовал хук user_register
(срабатывает при регистрации пользователя) и создавал ключ (например, хешировал время, email пользователя и случайную строку), сохраняя этот ключ в таблице usermeta. Этот ключ удаляется после активации аккаунта.
Чтобы неактивированный пользователь не мог войти, я добавил дополнительные проверки при авторизации, используя хук authenticate
. Например:
Правка
Согласно комментариям, фильтр authenticate
должен возвращать объект WP_Error
при ошибке, в противном случае — null. Функция wp_authenticate_username_password
выполняется после этого, и если ей передается объект WP_User
, она не выполняет проверки, предполагая, что они уже сделаны.
Обновленный код возвращает переданный объект или WP_Error
, если ключ активации существует (т.е. пользователь еще не активировал аккаунт).
add_filter( 'authenticate', 'wpse32218_check_for_key', 10, 3 );
function wpse32218_check_for_key( $user, $username, $password ){
$user_obj = get_user_by('login', $username );
if ($username!=''){
$value = get_user_meta($user->ID, 'confirmed', true);
if($value!=null){
$user = new WP_Error( 'denied', __("<strong>ОШИБКА</strong>: Вам нужно активировать ваш аккаунт.".$value."") ); // Создаем ошибку
remove_action('authenticate', 'wp_authenticate_username_password', 20); // Ключ найден — дальше не проверяем!
}
}
return $user;
}
(Можно использовать shake_error_codes
, чтобы форма входа "тряслась" при обнаружении ключа, если хотите :D).
Затем в вашем плагине нужно переопределить функцию wp_new_user_notification
(эта "подключаемая" функция находится в /wp_includes/pluggable.php
). Она отправляет email новому пользователю и администратору.
Скопируйте эту функцию в свой плагин внутри:
if ( !function_exists('wp_new_user_notification') ) :
// Здесь определите свою функцию wp_new_user_notification
endif;
и адаптируйте её, чтобы она извлекала и включала ключ активации в сообщение для пользователя.
В моем проекте я создал ссылку с ключом активации, по которой пользователь мог кликнуть для активации. Например, если ключ — 01234ABCDE: http://www.example.com?confirm=01234ABCDE.
С помощью фильтра query_vars
я зарегистрировал переменную 'confirm' в WordPress. Затем, используя фильтр template_include
, при обнаружении этой переменной (как в примере выше) я перенаправлял пользователя на confirm.php
(файл-шаблон в директории темы).
Этот шаблон пытается найти пользователя с соответствующим ключом. Если находит — удаляет ключ. Теперь аккаунт активен, и пользователь может войти. Если ключ не найден или аккаунт уже активирован, выводится сообщение об ошибке. Если ключ дублируется (чего быть не должно), также выводится ошибка.

Вау, спасибо! Уверен, что смогу реализовать это уже сегодня вечером с вашей помощью.

Просто предупреждение. Очень серьезное предупреждение! Я использовал этот код в небольшом плагине, который разработал для отображения двух полей пароля (второе для подтверждения совпадения) на форме регистрации, чтобы пользователи могли выбирать свой собственный пароль. После активации плагина и тестирования я обнаружил, что пользователи могли вводить любую комбинацию текста для пароля, а не ту, которую они выбрали изначально. Очень опасно. После некоторых проверок оказалось, что именно этот блок кода вызывал проблему. Теперь я обхожусь без этого кода.

Фил прав в своем предупреждении, этот код имеет серьезный изъян. Но его легко исправить. Просто удалите return $user, и вы залатаете эту дыру в безопасности.

@Phil @Scott Спасибо, что обратили на это внимание. Я исправил код. Если функции wp_authenticate_username_password
передается объект пользователя, она пропускает аутентификацию. Новая функция возвращает то, что ей передали, и только объект ошибки, если аккаунт не активирован. Это позволяет плагинам реализовать собственную функцию аутентификации, которая выполняется перед этой.

@StephenHarris вы не думали поделиться этим в виде плагина? Насколько я знаю, сейчас ничего подобного нет. Лично я не могу отложить другие задачи, чтобы начать работать с PHP. Такой плагин был бы огромным подспорьем. Спасибо!
