Как сделать вход только по email без логина?
После нескольких дней поиска и чтения двухлетних обсуждений, я испытываю трудности с поиском решения для входа пользователей только по email.
Сначала я обрадовался, увидев WP_Email_Login, но оказалось, что все равно можно использовать логин для входа. Я не уверен, как реализовать это в виде плагина. Моя идея заключается в переопределении функции register_new_user. Я не нашел ее в списке "pluggable" функций. Можно ли использовать фильтры/действия для достижения этой цели?
Я понимаю, что редактировать файлы ядра не рекомендуется, поэтому надеюсь найти другое решение. Однако, если такового не существует, я рискну. В первой строке функции "register_new_user" в wp-login.php я могу добавить:
$nickname_variable(??) = $user_login // установить nickname равным логину
$user_login = $user_email; // установить user_login/username равным email адресу
Это работает довольно хорошо, так как WordPress не позволяет пользователям менять свой логин. На экране регистрации (в форме) запрашивается Логин и Email; я хотел бы установить Логин равным переменной Nickname (если кто-то может подсказать, как называется переменная nickname или где она устанавливается во время регистрации, буду признателен).
С уважением,
Smith

Обновление: Я создал плагин для входа, регистрации и восстановления пароля по email. https://wordpress.org/plugins/smart-wp-login/
Короткий ответ: вы можете настроить WordPress для входа с помощью email.
Три шага:
- Удалить стандартную функцию аутентификации
- Добавить пользовательскую функцию аутентификации
- Изменить текст "Username" в wp-login.php на "Email"
Одно замечание:
- Не редактируйте файлы ядра WordPress.
Удаление стандартной функции аутентификации WordPress
WordPress использует фильтр "authenticate" для выполнения дополнительной проверки при входе пользователя.
remove_filter('authenticate', 'wp_authenticate_username_password', 20);
Добавление пользовательской функции аутентификации
add_filter('authenticate', function($user, $email, $password){
//Проверка на пустые поля
if(empty($email) || empty ($password)){
//Создаем новый объект ошибки и добавляем в него ошибки
$error = new WP_Error();
if(empty($email)){ //Пустой email
$error->add('empty_username', __('<strong>ОШИБКА</strong>: Поле email пустое.'));
}
else if(!filter_var($email, FILTER_VALIDATE_EMAIL)){ //Неверный формат email
$error->add('invalid_username', __('<strong>ОШИБКА</strong>: Неверный формат email.'));
}
if(empty($password)){ //Пустой пароль
$error->add('empty_password', __('<strong>ОШИБКА</strong>: Поле пароля пустое.'));
}
return $error;
}
//Проверяем существование пользователя в базе WordPress
$user = get_user_by('email', $email);
//Неверный email
if(!$user){
$error = new WP_Error();
$error->add('invalid', __('<strong>ОШИБКА</strong>: Введен неверный email или пароль.'));
return $error;
}
else{ //Проверка пароля
if(!wp_check_password($password, $user->user_pass, $user->ID)){ //Неверный пароль
$error = new WP_Error();
$error->add('invalid', __('<strong>ОШИБКА</strong>: Введен неверный email или пароль.'));
return $error;
}else{
return $user; //Успешно
}
}
}, 20, 3);
Изменение текста "Username" в wp-login.php на "Email"
Мы можем использовать фильтр gettext для изменения текста "Username" на "Email" без редактирования файлов ядра.
add_filter('gettext', function($text){
if(in_array($GLOBALS['pagenow'], array('wp-login.php'))){
if('Username' == $text){
return 'Email';
}
}
return $text;
}, 20);
Я также написал подробную статью в своем блоге http://www.thebinary.in/blog/wordpress-login-using-email/

Это возможно, вам необходимо изменить стандартную проверку с помощью фильтра действий.
// Удаляем стандартный фильтр.
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// Добавляем пользовательский фильтр.
add_filter( 'authenticate', 'fb_authenticate_username_password', 20, 3 );
function fb_authenticate_username_password( $user, $username, $password ) {
// Если в поле имени пользователя введен email,
// ищем соответствующее имя пользователя и проводим аутентификацию как обычно.
if ( ! empty( $username ) )
$user = get_user_by( 'email', $username );
if ( isset( $user->user_login, $user ) )
$username = $user->user_login;
// используем имя пользователя, найденное при поиске по email
return wp_authenticate_username_password( NULL, $username, $password );
}
Альтернативный вариант — использование публичного плагина.

Спасибо за ответ, но я не уверен, прочитали ли вы мой пост или, возможно, я был недостаточно ясен. Приношу извинения, если это так. В своем исходном посте я упомянул плагин WP_Email_Login — именно тот плагин, из которого взяты ваш код и ссылка. Вот мой оригинальный пост: "Сначала я обрадовался, увидев WP_Email_Login, но затем обнаружил, что по-прежнему можно использовать имя пользователя для входа." <--- Видите проблему? Я все еще могу использовать имя пользователя, поэтому этот плагин не подходит. Поскольку я не могу полностью избавиться от имен пользователей, я думаю о переопределении функции регистрации, заставляя имя пользователя равняться email-адресу.

Однако я ищу способ реализовать это без редактирования основных файлов. Если это невозможно — ничего страшного, но я хотел бы знать наверняка. Спасибо!

Используя приведенный выше код:
// Изменение учетных данных для входа
// удаляем стандартный фильтр
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// добавляем пользовательский фильтр
add_filter( 'authenticate', 'my_authenticate_username_password', 20, 3 );
function my_authenticate_username_password( $user, $username, $password ) {
// Если в поле имени пользователя введен email,
// находим соответствующее имя пользователя и аутентифицируем как обычно.
if ( ! empty( $username ) ) {
// если имя пользователя не содержит @, устанавливаем его как пустую строку
// что приводит к ошибке аутентификации
if(strpos($username, '@') == FALSE){
$username = '';
}
$user = get_user_by( 'email', $username );
}
if ( isset( $user->user_login, $user ) )
$username = $user->user_login;
// используем имя пользователя, найденное при поиске по email
return wp_authenticate_username_password( NULL, $username, $password );
}
Все, что нам нужно было сделать — проверить, что предоставленное имя пользователя хотя бы выглядит как email, и если нет — саботировать имя пользователя.

Вместо примитивной проверки строки на наличие символа '@'
в имени пользователя, WordPress имеет удобную встроенную функцию: sanitize_email возвращает либо корректный формат email-адреса, либо ничего: sanitize_email('email¬!"@business_com'); // Возвращает ничего

Небольшие изменения в приведенном выше коде — это все, что потребуется для создания элегантного решения. В документации по хуку authenticate указано, что должен возвращаться либо объект WP_User
, либо объект WP_Error
.
В исходном коде функции wp_authenticate_username_password выполняются довольно простые проверки; мы можем просто повторить их логику и создать новый объект WP_Error
для обработки email-адреса. В качестве альтернативы, мы могли бы даже заимствовать код wp_authenticate_username_password
и изменить его, если бы захотели, хотя это кажется излишним, если только вам действительно не нужно кастомизировать логику работы. Следующий код должен сработать: (Хотя я сам его не тестировал...)
// Удаляем стандартную функцию аутентификации
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// Добавляем кастомную функцию аутентификации
add_filter( 'authenticate', 'custom_authenticate_username_password', 20, 3 );
function custom_authenticate_username_password( $user, $username, $password ) {
// Получаем объект WP_User по email-адресу
if ( ! empty( $username ) ) {
$user = get_user_by( 'email', $username );
}
// Возвращаем кастомный объект WP_Error, если не удалось получить объект WP_User (например, email не существует или было введено обычное имя пользователя)
if ( ! $user ) {
return new WP_Error( 'invalid_username_email', sprintf( __( '<strong>ОШИБКА</strong>: Неверное имя пользователя. Пожалуйста, войдите, используя ваш email-адрес. <a href="%s" title="Забыли пароль">Забыли пароль</a>?' ), wp_lostpassword_url() ) );
}
// Возвращаем управление стандартному обработчику аутентификации, теперь, когда у нас есть валидный объект WP_User на основе email-адреса
return wp_authenticate_username_password( null, $username, $password );
}

Я знаю, что это довольно старая тема, но она часто появляется в результатах поиска Google, поэтому решил добавить ответ.
Начиная с версии 4.5.0 WordPress имеет функцию wp_authenticate_email_password
(документация), которая подключена к фильтру authenticate
.
Таким образом, чтобы разрешить аутентификацию только по email, вам просто нужно удалить аутентификацию по имени пользователя, как показано в других ответах:
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
Этого должно быть достаточно.

Для этого есть плагин: Force Email Login
https://wordpress.org/plugins/force-email-login/
Он также доступен на Github: https://github.com/miya0001/force-email-login

Отлично. Вы можете просто поместить https://raw.githubusercontent.com/miya0001/force-email-login/master/force-email-login.php в mu-plugins

Я долго пытался сделать это без написания кода, и многие из предлагаемых здесь плагинов больше не поддерживаются. Я нашел этот, который отлично справляется: https://wordpress.org/plugins/login-customizer/.
Он также выполняет другие функции, но при этом остается очень легковесным.

Измените тип поля с text на email, чтобы поле выдавало ошибку, если пользователь попытается ввести имя пользователя и пароль и нажать вход
<input type="email" name="username" id="username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" />
кнопка
