¿Puedo iniciar sesión de un usuario programáticamente sin contraseña?

28 may 2012, 16:13:10
Vistas: 118K
Votos: 51

Estoy creando usuarios manualmente de forma programática y quiero iniciar sesión con el usuario recién creado. WordPress facilita el acceso a la contraseña hasheada, pero no a la versión en texto plano. ¿Hay alguna manera de usar wp_signon() sin la contraseña en texto plano?

Encontré a una persona que dice haberlo logrado aquí, pero no funcionó para mí.

¡GRACIAS!

1
Comentarios

Creo que puedes simplemente asignar el objeto de usuario que acabas de crear a la variable global current_user

onetrickpony onetrickpony
28 may 2012 16:27:58
Todas las respuestas a la pregunta 7
4
66

El siguiente código realiza el inicio de sesión automático, ¡sin necesidad de contraseña!

// Inicio de sesión automático //
$username = "Admin";
$user = get_user_by('login', $username );

// URL de redirección //
if ( !is_wp_error( $user ) )
{
    wp_clear_auth_cookie();
    wp_set_current_user ( $user->ID );
    wp_set_auth_cookie  ( $user->ID );

    $redirect_to = user_admin_url();
    wp_safe_redirect( $redirect_to );
    exit();
}
3 ene 2014 15:21:12
Comentarios

Funciona muy bien. Con solo el nombre de usuario es suficiente, que no distingue entre mayúsculas y minúsculas.

shasi kanth shasi kanth
6 feb 2014 09:50:52

get_user_by() devuelve false en caso de fallo, por lo que deberías comprobar si es false en lugar del objeto WP_Error

somebodysomewhere somebodysomewhere
14 abr 2016 23:41:21

@Sjoerd Linders, ¿dónde puedo enganchar tu script para forzar a que un usuario esté conectado?

RafaSashi RafaSashi
31 ago 2016 19:45:14

¿Dónde coloco este bloque de código y en qué archivo?

sgiri sgiri
28 may 2019 10:32:51
4
43

wp_set_auth_cookie() iniciará sesión a un usuario sin necesidad de conocer su contraseña.

28 may 2012 16:25:39
Comentarios

Esto funcionó muy bien. Sin embargo, cuando lo uso, el condicional is_user_logged_in() no parece funcionar. ¿Sabes si está verificando algo diferente a las cookies?

emersonthis emersonthis
28 may 2012 16:44:12

@Emerson - ¿en qué hook estás iniciando su sesión? Tiene que ser antes de que se envíen las cabeceras. También intenta usar wp_set_current_user antes de iniciar su sesión.

Milo Milo
28 may 2012 16:47:31

En realidad no lo estaba llamando desde un hook. Solo agregué wp_set_auth_cookie() en mi función de inicio de sesión. Supongo que necesito reconsiderar eso. También investigaré sobre wp_set_current_user y reportaré los resultados. ¡Muchas gracias por tu ayuda con esto!

emersonthis emersonthis
28 may 2012 16:59:58

Bueno, ¿es posible iniciar sesión de un usuario sin que sus datos existan en la base de datos? ¿Es suficiente con configurar algunas cookies en el navegador mediante un script? Por favor, házmelo saber.

shasi kanth shasi kanth
6 feb 2014 11:10:41
5
15

He encontrado otra solución aquí que utiliza un enfoque mejor (al menos en mi opinión...). No es necesario configurar ninguna cookie, utiliza la API de Wordpress:

/**
 * Inicia sesión de un usuario de forma programática
 * 
 * @param string $username
 * @return bool True si el inicio de sesión fue exitoso; false si no lo fue
 */
function programmatic_login( $username ) {
    if ( is_user_logged_in() ) {
        wp_logout();
    }

    add_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );    // Se engancha antes que otros callbacks para interrumpirlos
    $user = wp_signon( array( 'user_login' => $username ) );
    remove_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );

    if ( is_a( $user, 'WP_User' ) ) {
        wp_set_current_user( $user->ID, $user->user_login );

        if ( is_user_logged_in() ) {
            return true;
        }
    }

    return false;
}

/**
 * Un callback del filtro 'authenticate' que autentica al usuario usando solo el nombre de usuario.
 *
 * Para evitar posibles vulnerabilidades de seguridad, esto solo debe usarse en el contexto de un inicio de sesión programático,
 * y debe desengancharse inmediatamente después de ejecutarse.
 * 
 * @param WP_User $user
 * @param string $username
 * @param string $password
 * @return bool|WP_User Un objeto WP_User si el nombre de usuario coincide con un usuario existente, o false si no
 */
function allow_programmatic_login( $user, $username, $password ) {
    return get_user_by( 'login', $username );
}

Creo que el código se explica por sí mismo:

El filtro busca el objeto WP_User para el nombre de usuario dado y lo devuelve. Una llamada a la función wp_set_current_user con el objeto WP_User devuelto por wp_signon, una verificación con la función is_user_logged_in para asegurarse de que estás conectado, ¡y eso es todo!

¡Un código limpio y elegante en mi opinión!

31 jul 2014 17:56:52
Comentarios

¿dónde usar programmatic_login?

RafaSashi RafaSashi
31 ago 2016 19:50:13

¡Respuesta perfecta!

Maximus Maximus
9 jul 2017 02:05:15

@Shebo Tu comentario no parece ser correcto. La primera línea de la función verifica si el array $credentials está vacío o no. Si el array no está vacío (que es el caso en mi respuesta), los valores del array se utilizan para autenticar al usuario.

Mike Mike
4 sept 2017 12:17:55

@Mike wow, cómo pude perdérmelo... Mi error, disculpas por la confusión. Eliminaré mi primer comentario para evitar confusiones. Aunque es una gran solución :)

Shebo Shebo
4 sept 2017 14:49:46

Podría valer la pena envolver wp_signon() en un bloque try y llamar a remove_filter en el bloque finally. Esto debería asegurar que el filtro siempre se elimine.

Leukipp Leukipp
23 jul 2020 06:35:30
1
10

Esto funciona bien para mí:

  clean_user_cache($user->ID);
  wp_clear_auth_cookie();
  wp_set_current_user($user->ID);
  wp_set_auth_cookie($user->ID, true, false);
  update_user_caches($user);
10 jun 2015 02:25:23
Comentarios

Este excelente artículo explica por qué esto es necesario: https://tommcfarlin.com/wordpress-user-caches/

Alex Alex
9 mar 2023 11:53:13
0

Además de Mike, Paul y Sjoerd:

Para manejar mejor las redirecciones de login.php:

//---------------------Inicio de sesión automático--------------------

if(!is_user_logged_in()){

    $username = "user1";

    if($user=get_user_by('login',$username)){

        clean_user_cache($user->ID);

        wp_clear_auth_cookie();
        wp_set_current_user( $user->ID );
        wp_set_auth_cookie( $user->ID , true, false);

        update_user_caches($user);

        if(is_user_logged_in()){

            $redirect_to = user_admin_url();
            wp_safe_redirect( $redirect_to );
            exit;
        }
    }
}
elseif('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] == wp_login_url()){

    $redirect_to = user_admin_url();
    wp_safe_redirect( $redirect_to );
    exit;
}

Se debe colocar en wp-config.php justo después de

require_once(ABSPATH . 'wp-settings.php');

Para tu información

Basado en la solución anterior, he lanzado un plugin para mantener al usuario conectado de un WordPress a otro sincronizando los datos del usuario y la sesión de cookies:

https://wordpress.org/plugins/user-session-synchronizer/

31 ago 2016 20:37:10
1

Curiosamente, la única forma en que funciona para mí es si redirecciono y uso die() después:

clean_user_cache($user->ID);
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true, true );
update_user_caches( $user );

if ( is_user_logged_in() ) {

    $redirect_to = $_SERVER['REQUEST_URI'];
    header("location:".$redirect_to );
    die(); 

}
22 may 2020 08:36:01
Comentarios

Puedes configurar la variable $redirect_to a cualquier página existente en tu sitio. Ej: $redirect_to = site_url();

Marcelo Viana Marcelo Viana
25 feb 2021 19:32:14
0

Creo que este es el camino correcto. Deberíamos limpiar la caché y las cookies del usuario. Después de iniciar sesión, necesitamos activar el hook wp_login para que otros plugins y funciones del núcleo funcionen en conjunto.

$user = get_user_by( 'ID', $user_id ); // Obtener WP_User desde el ID de usuario.
// $user = get_user_by( 'email', $email ); // O obtener desde el email.
// $user = get_user_by( 'login', $username ); // O obtener desde el nombre de usuario.

if ( false !== $user ) {
    clean_user_cache( $user->ID );
    wp_clear_auth_cookie();
    wp_set_current_user( $user->ID, $user->user_login );
    wp_set_auth_cookie( $user->ID );
    update_user_caches( $user );
    do_action( 'wp_login', $user->user_login, $user );
}
13 ene 2024 16:56:10