Как сделать вход только по email без логина?

9 мая 2012 г., 23:44:26
Просмотры: 46.4K
Голосов: 25

После нескольких дней поиска и чтения двухлетних обсуждений, я испытываю трудности с поиском решения для входа пользователей только по 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

6
Комментарии

Вы пытаетесь полностью избавиться от имен пользователей? Почему плагин Email Login вам не подходит?

Ryan Ryan
10 мая 2012 г. 01:40:07

Мне действительно интересно, зачем вам избавляться от имен пользователей, ведь они являются основой всей пользовательской информации в WordPress. Это похоже на попытку избавиться от Записей — много работы с минимальной выгодой и гарантированными проблемами в будущем.

SickHippie SickHippie
10 мая 2012 г. 02:00:16

@Ryan - Думаю, мне не удастся полностью убрать имена пользователей, поэтому я просто принудительно делаю имя пользователя равным email-адресу.

agentsmith666 agentsmith666
10 мая 2012 г. 09:29:46

@SickHippie - для входа я считаю email лучше и более уникальным, чем имя пользователя. Я предпочитаю использовать имя пользователя как никнейм при публикации. Ты прав, было бы проблематично "избавиться" от переменной "username", поэтому я этого и не делаю. Я просто выбираю имя пользователя автоматически при регистрации (username будет их email-адресом; их никнеймом будет то, что они ввели как имя пользователя). В итоге никакие переменные не теряются, всё остаётся на своих местах.

agentsmith666 agentsmith666
10 мая 2012 г. 09:34:30

Но если имена пользователей нельзя изменить (поведение WordPress по умолчанию), что произойдёт, когда пользователь сменит email? Например, если пользователь уйдёт с Hotmail на Gmail, он останется привязанным к Hotmail для входа на ваш сайт? Если нет, то он сможет изменить email, но продолжать использовать старый email для входа (как username), и вы окажетесь в той же ситуации. Нет смысла искусственно ограничивать варианты входа пользователей, создавая себе лишнюю работу для решения, которое не решает никаких проблем. Кроме того, имена пользователей и так уникальны. WordPress это обеспечивает.

SickHippie SickHippie
10 мая 2012 г. 19:47:29

@SickHippie - Ты прав, поскольку WordPress по умолчанию не позволяет пользователям менять имя пользователя, их username/email останется прежним, даже если они изменят контактный email. Я учитывал это с самого начала, и по своему опыту заметил, что люди редко "удаляют" email-адреса. Они могут завести новые, но обычно сохраняют старые. А если нет — в редких случаях мы можем изменить это вручную в базе данных. Я очень ценю твои отзывы и советы, SickHippie! Теперь надеюсь на решение своего вопроса :)

agentsmith666 agentsmith666
13 мая 2012 г. 09:43:48
Показать остальные 1 комментариев
Все ответы на вопрос 9
2
25

Обновление: Я создал плагин для входа, регистрации и восстановления пароля по 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/

12 июн. 2014 г. 16:59:14
Комментарии

Хороший ответ, Нишант

Andrew Bartel Andrew Bartel
12 июн. 2014 г. 19:21:00

Полезно! В моем случае я просто удаляю специальные символы из email и использую его как имя пользователя. Например, user@example.com становится user_example_com, и это сработало.

wpcoder wpcoder
28 апр. 2018 г. 23:01:53
3

Это возможно, вам необходимо изменить стандартную проверку с помощью фильтра действий.

// Удаляем стандартный фильтр.
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 );
}

Альтернативный вариант — использование публичного плагина.

10 мая 2012 г. 08:48:50
Комментарии

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

agentsmith666 agentsmith666
10 мая 2012 г. 09:37:13

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

agentsmith666 agentsmith666
10 мая 2012 г. 09:41:54

Вот способ без редактирования основных файлов. Скопируйте код в плагин, активируйте его — и готово.

bueltge bueltge
2 апр. 2013 г. 01:06:27
1

Используя приведенный выше код:

// Изменение учетных данных для входа
// удаляем стандартный фильтр
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, и если нет — саботировать имя пользователя.

1 июн. 2013 г. 03:34:24
Комментарии

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

indextwo indextwo
7 июл. 2014 г. 13:16:51
0

Небольшие изменения в приведенном выше коде — это все, что потребуется для создания элегантного решения. В документации по хуку 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 );
}
19 февр. 2014 г. 21:31:10
1

это уже есть в WP-CORE!

Сейчас WordPress уже позволяет регистрироваться с EMAIL в качестве имени пользователя. Но если вы говорите о уже зарегистрированных пользователях, то попробуйте предложенные решения.

17 июл. 2016 г. 22:46:51
Комментарии

Ссылка на документацию WP, где это объясняется, была бы очень полезна. Не могли бы вы её предоставить? Я не смог найти её в своих поисках.

Gerard Reches Gerard Reches
26 апр. 2021 г. 14:39:12
0

Я знаю, что это довольно старая тема, но она часто появляется в результатах поиска Google, поэтому решил добавить ответ.

Начиная с версии 4.5.0 WordPress имеет функцию wp_authenticate_email_password (документация), которая подключена к фильтру authenticate.

Таким образом, чтобы разрешить аутентификацию только по email, вам просто нужно удалить аутентификацию по имени пользователя, как показано в других ответах:

remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);

Этого должно быть достаточно.

21 мая 2022 г. 15:24:06
1

Для этого есть плагин: Force Email Login

https://wordpress.org/plugins/force-email-login/

Он также доступен на Github: https://github.com/miya0001/force-email-login

17 апр. 2018 г. 17:29:24
Комментарии

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

squarecandy squarecandy
15 февр. 2020 г. 01:01:08
1

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

Он также выполняет другие функции, но при этом остается очень легковесным.

8 мая 2021 г. 03:59:01
Комментарии

Привет и спасибо за участие в WPSE. В целом, мы стремимся к ответам с кодом или решениями для разработки, а не к рекомендациям плагинов.

Matthew Brown aka Lord Matt Matthew Brown aka Lord Matt
8 мая 2021 г. 20:11:03
0

Измените тип поля с text на email, чтобы поле выдавало ошибку, если пользователь попытается ввести имя пользователя и пароль и нажать вход

<input type="email" name="username" id="username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" />

кнопкаОписание изображения кнопки входа

27 апр. 2023 г. 18:43:13