Posso effettuare il login programmatico di un utente senza password?
Sto creando utenti manualmente in modo programmatico e vorrei effettuare l'accesso per l'utente appena creato. WordPress rende facile accedere alla password criptata, ma non alla versione in chiaro. Esiste un modo per utilizzare wp_signon() senza la password in chiaro?
Ho trovato una persona che afferma di averlo fatto qui, ma non ha funzionato nel mio caso.
GRAZIE!

Il seguente codice permette il login automatico, senza alcuna password!
// Login automatico //
$username = "Admin";
$user = get_user_by('login', $username );
// URL di reindirizzamento //
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();
}

Funziona benissimo. Basta il nome utente, che non è sensibile alle maiuscole/minuscole.

get_user_by()
restituisce false in caso di fallimento, quindi dovresti verificare false invece dell'oggetto WP_Error

@Sjoerd Linders, dove posso agganciare il tuo script per forzare un utente a connettersi?

wp_set_auth_cookie()
permette di autenticare un utente senza dover conoscere la sua password.

Ha funzionato alla grande. Tuttavia, quando lo uso, il condizionale is_user_logged_in()
non sembra funzionare. Sai se sta controllando qualcosa di diverso dai cookie?

@Emerson - su quale hook li stai autenticando? Deve essere prima che gli header vengano inviati. Prova anche a usare wp_set_current_user
prima di autenticarli.

In realtà non lo stavo chiamando da un hook. Avevo semplicemente aggiunto wp_set_auth_cookie()
nella mia funzione di accesso. Immagino di dover ripensare a questo approccio. Cercherò anche wp_set_current_user e ti farò sapere. Grazie mille per il tuo aiuto!

Ho trovato un'altra soluzione qui che utilizza un approccio migliore (almeno secondo me...). Non è necessario impostare alcun cookie, utilizza l'API di Wordpress:
/**
* Effettua il login di un utente in modo programmatico
*
* @param string $username
* @return bool True se il login ha avuto successo; false in caso contrario
*/
function programmatic_login( $username ) {
if ( is_user_logged_in() ) {
wp_logout();
}
add_filter( 'authenticate', 'allow_programmatic_login', 10, 3 ); // hook con priorità più alta per evitare altri callback
$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 filtro 'authenticate' che autentica l'utente utilizzando solo lo username.
*
* Per evitare potenziali vulnerabilità di sicurezza, questa funzione dovrebbe essere usata solo
* nel contesto di un login programmatico e rimossa immediatamente dopo l'uso.
*
* @param WP_User $user
* @param string $username
* @param string $password
* @return bool|WP_User un oggetto WP_User se lo username corrisponde a un utente esistente, oppure false
*/
function allow_programmatic_login( $user, $username, $password ) {
return get_user_by( 'login', $username );
}
Penso che il codice sia autoesplicativo:
Il filtro cerca l'oggetto WP_User per lo username fornito e lo restituisce.
Una chiamata alla funzione wp_set_current_user
con l'oggetto WP_User restituito da wp_signon
, un controllo con la funzione is_user_logged_in
per assicurarsi di essere loggati, e il gioco è fatto!
Un codice bello e pulito secondo me!

@Shebo Il tuo commento non sembra corretto. La prima riga della funzione controlla se l'array $credentials
è vuoto o meno. Se l'array non è vuoto (come nel caso della mia risposta), i valori dell'array vengono utilizzati per autenticare l'utente.

@Mike wow, come ho fatto a perderlo... Colpa mia, scusa per l'informazione fuorviante. Cancellerò il mio primo commento, per evitare confusione. Ottima soluzione comunque :)

Questo funziona bene per me:
clean_user_cache($user->ID); // Pulisce la cache dell'utente
wp_clear_auth_cookie(); // Rimuove i cookie di autenticazione
wp_set_current_user($user->ID); // Imposta l'utente corrente
wp_set_auth_cookie($user->ID, true, false); // Imposta nuovi cookie di autenticazione
update_user_caches($user); // Aggiorna le cache dell'utente

Questo interessante articolo fornisce una spiegazione sul perché ciò sia necessario: https://tommcfarlin.com/wordpress-user-caches/

Oltre a Mike, Paul e Sjoerd:
Per gestire meglio i reindirizzamenti di login.php
:
//---------------------Login automatico--------------------
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;
}
Da inserire in wp-config.php
subito dopo
require_once(ABSPATH . 'wp-settings.php');
Per tua informazione
Basandomi sulla soluzione sopra, ho rilasciato un plugin per mantenere l'utente loggato da un WordPress a un altro sincronizzando i dati utente e la sessione dei cookie:

Stranamente, l'unico modo in cui funziona per me è se faccio un redirect e die() dopo:
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();
}

Penso sia la strada giusta. Dovremmo pulire la cache e i cookie dell'utente. Dopo il login, dobbiamo attivare l'hook wp_login
per far lavorare insieme altri plugin e le funzioni del core.
$user = get_user_by( 'ID', $user_id ); // Ottieni WP_User dall'ID utente.
// $user = get_user_by( 'email', $email ); // Oppure ottieni dall'email.
// $user = get_user_by( 'login', $username ); // Oppure ottieni dallo username.
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 );
}
