¿Cómo iniciar sesión solo con email sin nombre de usuario?
Después de buscar durante un par de días y leer hilos de hace 2 años, estoy teniendo dificultades para encontrar una solución al problema de hacer que los usuarios inicien sesión solo con el email.
Al principio me alegré de ver WP_Email_Login, solo para descubrir que aún se puede usar el nombre de usuario para iniciar sesión. No estoy seguro de cómo escribir esto como un plugin. Mi idea es sobrescribir la función register_new_user. No vi esto en la lista de funciones "pluggable". ¿Puedo usar filtros/acciones para lograr esto?
Entiendo que no es recomendable editar los archivos del núcleo, así que espero que exista una solución, sin embargo, si no existe, me arriesgaré. En la primera línea de la función "register_new_user" en wp-login.php puedo agregar:
$nickname_variable(??) = $user_login // establecer el nickname como el nombre de usuario
$user_login = $user_email; // establecer el user_login/nombre de usuario como la dirección de email
Esto funciona bastante bien ya que WordPress no permite que las personas cambien su nombre de usuario. En la pantalla de registro (formulario) solicita el Nombre de usuario y Email; me gustaría establecer el Nombre de usuario como la variable nickname (si alguien puede decirme cómo se llama la variable nickname o dónde se establece durante el registro, lo agradecería).
Saludos,
Smith

Actualización: He creado un plugin para inicio de sesión, registro y recuperación de contraseña con correo electrónico. https://wordpress.org/plugins/smart-wp-login/
Respuesta corta: puedes configurar WordPress para iniciar sesión con correo electrónico.
Tres pasos:
- Eliminar la función de autenticación predeterminada
- Añadir una función de autenticación personalizada
- Cambiar el texto "Nombre de usuario" en wp-login.php por "Correo electrónico"
Una nota:
- No edites los archivos principales (core files).
Eliminar la función de autenticación predeterminada de WordPress.
WordPress usa el filtro "authenticate" para realizar validaciones adicionales al iniciar sesión.
remove_filter('authenticate', 'wp_authenticate_username_password', 20);
Añadir una función de autenticación personalizada
add_filter('authenticate', function($user, $email, $password){
//Verificar campos vacíos
if(empty($email) || empty ($password)){
//Crear nuevo objeto de error y añadir errores
$error = new WP_Error();
if(empty($email)){ //Sin correo
$error->add('empty_username', __('<strong>ERROR</strong>: El campo de correo electrónico está vacío.'));
}
else if(!filter_var($email, FILTER_VALIDATE_EMAIL)){ //Correo inválido
$error->add('invalid_username', __('<strong>ERROR</strong>: El correo electrónico es inválido.'));
}
if(empty($password)){ //Sin contraseña
$error->add('empty_password', __('<strong>ERROR</strong>: El campo de contraseña está vacío.'));
}
return $error;
}
//Verificar si el usuario existe en la base de datos de WordPress
$user = get_user_by('email', $email);
//correo incorrecto
if(!$user){
$error = new WP_Error();
$error->add('invalid', __('<strong>ERROR</strong>: El correo electrónico o la contraseña ingresados son incorrectos.'));
return $error;
}
else{ //verificar contraseña
if(!wp_check_password($password, $user->user_pass, $user->ID)){ //contraseña incorrecta
$error = new WP_Error();
$error->add('invalid', __('<strong>ERROR</strong>: El correo electrónico o la contraseña ingresados son incorrectos.'));
return $error;
}else{
return $user; //aprobado
}
}
}, 20, 3);
Cambiar el texto "Nombre de usuario" en wp-login.php por "Correo electrónico"
Podemos usar el filtro gettext para cambiar el texto "Nombre de usuario" por "Correo electrónico" sin editar los archivos principales.
add_filter('gettext', function($text){
if(in_array($GLOBALS['pagenow'], array('wp-login.php'))){
if('Username' == $text){
return 'Correo electrónico';
}
}
return $text;
}, 20);
También he escrito un artículo detallado en mi blog http://www.thebinary.in/blog/wordpress-login-using-email/

Es posible, debes cambiar la validación predeterminada mediante el filtro de acción.
// Eliminar el filtro predeterminado.
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// Agregar filtro personalizado.
add_filter( 'authenticate', 'fb_authenticate_username_password', 20, 3 );
function fb_authenticate_username_password( $user, $username, $password ) {
// Si se ingresa una dirección de correo electrónico en el campo de nombre de usuario,
// entonces busca el nombre de usuario correspondiente y autentica normalmente usando ese.
if ( ! empty( $username ) )
$user = get_user_by( 'email', $username );
if ( isset( $user->user_login, $user ) )
$username = $user->user_login;
// usando el nombre de usuario encontrado al buscar por correo electrónico
return wp_authenticate_username_password( NULL, $username, $password );
}
Una alternativa es un plugin público.

Gracias por la respuesta, sin embargo no estoy seguro si leíste mi publicación o si no fui lo suficientemente claro. Me disculpo por lo segundo. En mi publicación original mencioné el plugin WP_Email_Login; el mismo plugin del que proviene tu código y enlace. Aquí está mi publicación original: "Al principio me emocioné al ver WP_Email_Login solo para descubrir que aún puedes usar tu nombre de usuario para iniciar sesión." <--- ¿Ves el problema? Todavía puedo usar un nombre de usuario, por eso este plugin no funcionará. Como no puedo eliminar los nombres de usuario, estoy pensando en anular la función de registro forzando que el nombre de usuario sea igual a la dirección de correo electrónico.

Sin embargo, estoy buscando una forma de lograr esto sin editar los archivos principales. Si no es posible, está bien, pero me gustaría saber de cualquier manera. ¡Gracias!

Utilizando el código anterior:
// Cambiar credenciales de inicio de sesión
// eliminar el filtro por defecto
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// agregar filtro personalizado
add_filter( 'authenticate', 'my_authenticate_username_password', 20, 3 );
function my_authenticate_username_password( $user, $username, $password ) {
// Si se ingresa una dirección de email en el campo de nombre de usuario,
// entonces buscar el nombre de usuario correspondiente y autenticar normalmente
if ( ! empty( $username ) ) {
// si el nombre de usuario no contiene un @, establecer username como cadena vacía
// esto causa que la autenticación falle
if(strpos($username, '@') == FALSE){
$username = '';
}
$user = get_user_by( 'email', $username );
}
if ( isset( $user->user_login, $user ) )
$username = $user->user_login;
// utilizando el nombre de usuario encontrado al buscar por email
return wp_authenticate_username_password( NULL, $username, $password );
}
Todo lo que tuvimos que hacer fue verificar que el nombre de usuario proporcionado al menos pareciera un email y, si no, sabotear el nombre de usuario.

En lugar de la verificación primitiva de cadena para '@'
en el nombre de usuario, Wordpress tiene una función incorporada útil: sanitize_email devolverá un formato válido de dirección de correo electrónico o nada: sanitize_email('email¬!"@business_com'); // No devuelve nada

Pequeñas modificaciones al código anterior deberían ser suficientes para crear una solución elegante. La documentación para el hook authenticate indica que se debe retornar ya sea un objeto WP_User
o un objeto WP_Error
.
El código fuente de la función wp_authenticate_username_password realiza algunas verificaciones bastante simples; podemos simplemente replicar la forma en que se hacen esas verificaciones, y crear un nuevo objeto WP_Error
para manejar la dirección de correo electrónico. Alternativamente, incluso podríamos tomar el código de wp_authenticate_username_password
y modificarlo si quisiéramos, aunque eso parece innecesario a menos que realmente desees personalizar cómo funcionan las cosas. El siguiente código debería funcionar: (Aunque no lo he probado yo mismo...)
// Eliminar la función de autenticación por defecto
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// Añadir la función de autenticación personalizada
add_filter( 'authenticate', 'custom_authenticate_username_password', 20, 3 );
function custom_authenticate_username_password( $user, $username, $password ) {
// Obtener el objeto WP_User basado en la dirección de correo electrónico
if ( ! empty( $username ) ) {
$user = get_user_by( 'email', $username );
}
// Retornar un objeto WP_Error personalizado si no se retornó un objeto WP_User (ej. El correo no existe o se proporcionó un nombre de usuario normal)
if ( ! $user ) {
return new WP_Error( 'invalid_username_email', sprintf( __( '<strong>ERROR</strong>: Nombre de usuario inválido. Por favor inicia sesión con tu dirección de correo electrónico. <a href="%s" title="Contraseña perdida y encontrada">¿Perdiste tu contraseña?</a>' ), wp_lostpassword_url() ) );
}
// Devolver el control de autenticación al manejador por defecto ahora que tenemos un objeto WP_User válido basado en el correo electrónico
return wp_authenticate_username_password( null, $username, $password );
}

Sé que este es un tema bastante antiguo pero aparece bastante alto en los resultados de Google, así que pensé en aportar una respuesta.
Desde la versión 4.5.0, WordPress incluye wp_authenticate_email_password
(documentación) que está enganchado al filtro authenticate
.
Por lo tanto, para permitir solo la autenticación por correo electrónico, solo tienes que eliminar la autenticación por nombre de usuario como se muestra en otras respuestas:
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
Eso debería ser todo lo que necesitas.

Hay un plugin para eso: Force Email Login
https://wordpress.org/plugins/force-email-login/
También está en Github: https://github.com/miya0001/force-email-login

Genial. Puedes simplemente colocar https://raw.githubusercontent.com/miya0001/force-email-login/master/force-email-login.php en mu-plugins

He estado luchando para hacer esto sin programar y muchos de los plugins propuestos aquí ya no tienen soporte. Encontré este que hace el trabajo: https://wordpress.org/plugins/login-customizer/.
También hace otras cosas, pero sigue siendo muy ligero.

Cambiar el tipo de campo de texto a email, para que el campo muestre un error si el usuario intenta ingresar el nombre de usuario y contraseña y presiona el botón de inicio de sesión
<input type="email" name="username" id="username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" />
botón
