Verificar nombre de usuario correcto en formulario de inicio de sesión personalizado

13 abr 2011, 23:24:15
Vistas: 30.6K
Votos: 11

He utilizado el tutorial de Jeff Star para crear mi propio formulario de inicio de sesión personalizado http://digwp.com/2010/12/login-register-password-code/. Funciona muy bien, pero tengo un problema. En el formulario de restablecimiento de contraseña, si alguien ingresa su nombre de usuario incorrectamente (de modo que no se verifica), son redirigidos a la página predeterminada wp-login.php?action=lostpassword con el mensaje de error.

¿Hay alguna manera de redirigir a mi propia página de error?

¡Gracias!

1
Comentarios

¿Tienes prisa, puede username_exists() ayudarte de alguna manera?

Ashfame Ashfame
13 abr 2011 23:29:41
Todas las respuestas a la pregunta 3
8
11

El código que publicó en ese tutorial (muy bueno por cierto) envía el formulario al módulo integrado de "restablecer contraseña" que redirige a login.php en caso de error, pero puedes modificarlo y crear tu propia versión basada en el original y agregarla a la página de plantilla, cambia:

<form method="post" action="<?php echo site_url('wp-login.php?action=lostpassword', 'login_post') ?>" class="wp-user-form">
    <div class="username">
        <label for="user_login" class="hide"><?php _e('Nombre de usuario o Email'); ?>: </label>
        <input type="text" name="user_login" value="" size="20" id="user_login" tabindex="1001" />
    </div>
    <div class="login_fields">
        <?php do_action('login_form', 'resetpass'); ?>
        <input type="submit" name="user-submit" value="<?php _e('Restablecer mi contraseña'); ?>" class="user-submit" tabindex="1002" />
        <?php $reset = $_GET['reset']; if($reset == true) { echo '<p>Se enviará un mensaje a tu dirección de correo electrónico.</p>'; } ?>
        <input type="hidden" name="redirect_to" value="<?php echo $_SERVER['REQUEST_URI']; ?>?reset=true" />
        <input type="hidden" name="user-cookie" value="1" />
    </div>
</form>

por:

<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>" class="wp-user-form">
<div class="username">
    <label for="user_login" class="hide"><?php _e('Nombre de usuario o Email'); ?>: </label>
    <input type="text" name="user_login" value="" size="20" id="user_login" tabindex="1001" />
</div>
<div class="login_fields">
    <?php do_action('login_form', 'resetpass'); ?>
    <input type="submit" name="user-submit" value="<?php _e('Restablecer mi contraseña'); ?>" class="user-submit" tabindex="1002" />

    <?php
    if (isset($_POST['reset_pass']))
    {
        global $wpdb;
        $username = trim($_POST['user_login']);
        $user_exists = false;
        if (username_exists($username))
        {
            $user_exists = true;
            $user_data = get_userdatabylogin($username);
        } elseif (email_exists($username))
        {

            $user_exists = true;
            $user = get_user_by_email($username);
        } else
        {
            $error[] = '<p>' . __('¡Nombre de usuario o Email no encontrado, inténtalo de nuevo!') . '</p>';
        }
        if ($user_exists)
        {
            $user_login = $user->user_login;
            $user_email = $user->user_email;
            // Generar algo aleatorio para la contraseña... md5 del tiempo actual con una sal aleatoria
            $key = substr(md5(uniqid(microtime())), 0, 8);
            // Insertar el nuevo pass md5 en la base de datos
            $wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
            //crear mensaje de email
            $message = __('Alguien ha solicitado restablecer la contraseña para el siguiente sitio y nombre de usuario.') . "\r\n\r\n";
            $message .= get_option('siteurl') . "\r\n\r\n";
            $message .= sprintf(__('Nombre de usuario: %s'), $user_login) . "\r\n\r\n";
            $message .= __('Para restablecer tu contraseña visita la siguiente dirección, de lo contrario ignora este email y no pasará nada.') . "\r\n\r\n";
            $message .= get_option('siteurl') . "/wp-login.php?action=rp&key=$key\r\n";
            //enviar mensaje de email
            if (FALSE == wp_mail($user_email, sprintf(__('[%s] Restablecimiento de contraseña'), get_option('blogname')), $message))
            $error[] = '<p>' . __('El correo electrónico no pudo ser enviado.') . "<br />\n" . __('Posible razón: tu servidor puede tener deshabilitada la función mail()...') . '</p>';
        }
        if (count($error) > 0)
        {
            foreach ($error as $e)
            {
                echo $e . '<br/>';
            }
        } else
        {
            echo '<p>' . __('Se enviará un mensaje a tu dirección de correo electrónico.') . '</p>';
        }
    }
    ?> 
    <input type="hidden" name="reset_pass" value="1" />
    <input type="hidden" name="user-cookie" value="1" />
</div>
</form>
14 abr 2011 01:18:01
Comentarios

Se ve genial, te aviso si funciona.

Pippin Pippin
14 abr 2011 23:28:09

Ok, he logrado que esto funcione muy bien, con solo algunos cambios. Había un par de errores de sintaxis y el generador de clave md5 no funcionaba, así que tomé el de wp-login.php. Solo tengo un problema ahora. Cuando alguien hace clic en el enlace del correo para crear una nueva contraseña, son redirigidos al formulario por defecto, así que ahora necesito crear un formulario para eso también.

Pippin Pippin
15 abr 2011 18:17:33

@pippin: el código del generador de clave md5 aquí es el de wp-login.php, y en cuanto a la redirección intenta agregar &redirect_to=$_SERVER['REQUEST_URI'] al enlace en el correo que envías.

Bainternet Bainternet
15 abr 2011 19:00:06

Mi enlace ahora se ve así $message .= get_option('siteurl') . "/wp-login.php?action=rp&key=$key&login=$user_login&redirect_to=$_SERVER['REQUEST_URI']\r\n";, pero lo extraño es que cuando agrego el &redirect, el mensaje no se envía... Además, ¿no necesitaré crear un nuevo formulario para que el usuario ingrese su nueva contraseña y demás?

Pippin Pippin
15 abr 2011 20:05:51

Sí, lo olvidé, necesitarías crear tu propio formulario para restablecer la contraseña y probablemente reemplazar el enlace que se envía al usuario por la URL actual, y basándote en la clave verificar si es el usuario y mostrarle el formulario.

Bainternet Bainternet
15 abr 2011 22:59:03

línea 17 get_user_by('login', $user_login); ya que get_userdatabylogin ha quedado obsoleto...

Val Val
15 may 2012 13:08:14

Me doy cuenta de que esta respuesta es bastante antigua, no estoy muy seguro de su fiabilidad. Supongo que debería funcionar, pero preferiría no meter mano al SQL ya que podría cambiar en el futuro. Por otro lado, no encuentro detalles sobre alternativas.

Christian Christian
25 feb 2013 10:27:50

"no meter mano al SQL"? está copiado del archivo del núcleo, nada más

Bainternet Bainternet
25 feb 2013 12:08:47
Mostrar los 3 comentarios restantes
0

Aquí está una versión actualizada del código de @bainternet con los errores de sintaxis corregidos, la sugerencia de @Val y el generador de claves de wp-login.php 3.4.2:

global $wpdb;
$username = trim($_POST['user_login']);
$user_exists = false;
// Primero verificar por nombre de usuario
if ( username_exists( $username ) ){
    $user_exists = true;
    $user = get_user_by('login', $username);
}
// Luego, por dirección de correo electrónico
elseif( email_exists($username) ){
        $user_exists = true;
        $user = get_user_by_email($username);
}else{
    $error[] = '<p>'.__('Nombre de usuario o correo electrónico no encontrado, ¡inténtalo de nuevo!').'</p>';
}
if ($user_exists){
    $user_login = $user->user_login;
    $user_email = $user->user_email;

    $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
    if ( empty($key) ) {
        // Generar algo aleatorio para la clave...
        $key = wp_generate_password(20, false);
        do_action('retrieve_password_key', $user_login, $key);
        // Ahora insertar la nueva clave md5 en la base de datos
        $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
    }

    //crear mensaje de correo electrónico
    $message = __('Alguien ha solicitado restablecer la contraseña para el siguiente sitio y nombre de usuario.') . "\r\n\r\n";
    $message .= get_option('siteurl') . "\r\n\r\n";
    $message .= sprintf(__('Nombre de usuario: %s'), $user_login) . "\r\n\r\n";
    $message .= __('Para restablecer tu contraseña visita la siguiente dirección, de lo contrario ignora este correo y no sucederá nada.') . "\r\n\r\n";
    $message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "&redirect_to=".urlencode(get_option('siteurl'))."\r\n";
    //enviar mensaje de correo electrónico
    if (FALSE == wp_mail($user_email, sprintf(__('[%s] Restablecimiento de contraseña'), get_option('blogname')), $message))
    $error[] = '<p>' . __('El correo electrónico no pudo ser enviado.') . "<br />\n" . __('Posible razón: tu servidor puede tener deshabilitada la función mail()...') . '</p>';
}
if (count($error) > 0 ){
    foreach($error as $e){
                echo $e . "<br/>";
            }
}else{
    echo '<p>'.__('Se enviará un mensaje a tu dirección de correo electrónico.').'</p>'; 
}
7 dic 2012 20:12:17
1

Todavía estaba teniendo problemas con que la clave de restablecimiento no funcionaba correctamente, el enlace en el correo electrónico me redirigía a la página estándar de restablecimiento de contraseña con el parámetro URL indicando un problema con la clave, así que seguí más de cerca el archivo wp-login.php e incluí el objeto $wp_hasher, esto solucionó el problema y ahora el restablecimiento de contraseña en el correo electrónico funciona

if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass']))) {

// Acceder a propiedades globales
global $wpdb, $wp_hasher;


// Variables
$error_pass_reset = array();
$username         = (string) trim($_POST['user_login']);
$user_exists      = (bool)   false;



// ---- USUARIO O EMAIL EXISTE ---- //
if (username_exists($username)) {
    $user_exists = (bool)   true;
    $user        = (object) get_user_by('login', $username);
} // end if

else if (email_exists($username)) {
    $user_exists = (bool)   true;
    $user        = (object) get_user_by('email', $username);
} // end else if

else {
    $error_pass_reset[] = '<p>No se encontró el nombre de usuario o correo electrónico, por favor intente nuevamente.</p>';
} // end else



// ---- EL USUARIO EXISTE ---- //
if ($user_exists === (bool) true) {
    // Variables
    $user_login = (string) $user -> user_login;
    $user_email = (string) $user -> user_email;


    // Generar clave de restablecimiento de contraseña
if (empty($key)) {
    $key = (string) wp_generate_password(20, false);

    do_action('retrieve_password_key', $user_login, $key);


    // Crear el objeto $wp_hasher
    if (empty($wp_hasher)) {
        require_once(ABSPATH . WPINC . '/class-phpass.php');

        $wp_hasher = new PasswordHash(8, true);
    }

    // Restablecer clave con hasher aplicado (MD5 tiene salida de cadena)
    $hashed = (string) time() . ':' . $wp_hasher -> HashPassword($key);


    // Insertar la nueva clave en la base de datos
    $wpdb -> update(
        $wpdb -> users,
        array(
            'user_activation_key' => $hashed
        ),
        array(
            'user_login' => $user_login
        )
    );
} // end if


    // Mensaje de correo electrónico
    $message = (string)
    'Alguien solicitó que se restablezca la contraseña para la siguiente cuenta:' . "\r\n\r\n" .

    get_option('siteurl') . "\r\n\r\n" .

    'Nombre de usuario: ' . $user_login . "\r\n\r\n" .
    'Si esto fue un error, simplemente ignore este correo electrónico y no pasará nada.' . "\r\n\r\n" .
    'Para restablecer su contraseña, visite la siguiente dirección:' . "\r\n\r\n" .

    get_option('siteurl') . '/wp-login.php?action=rp&key=' . $key . '&login=' . $user_login . "\r\n";


    // Enviar correo electrónico
    if ((bool) false === wp_mail($user_email, get_option('blogname') . ' Restablecimiento de Contraseña', $message)) {
        $error_pass_reset[] = '<p>El correo electrónico no pudo ser enviado en este momento.</p>' . "\n";
    } // end if
} // end if


// Enviar el correo electrónico de restablecimiento de contraseña
do_action('login_form', 'resetpass');

} // end if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass'])))
13 nov 2015 16:07:59
Comentarios

Esta respuesta con el código wp_hasher me fue extremadamente útil ya que he creado una plantilla personalizada para contraseña olvidada.

Neelam Khan Neelam Khan
31 ene 2017 17:52:04