Come verificare username/password senza autenticare l'utente
Sto sviluppando un plugin che crea un endpoint API per validare le coppie username/password.
Attualmente sto usando wp_signon()
per verificare se la combinazione username/password funziona. Questo funziona bene quando le credenziali falliscono perché restituisce un oggetto di errore. Ma quando le credenziali sono corrette, autentica automaticamente quell'utente, quindi il mio endpoint restituisce un'intera pagina.
Il codex attualmente non menziona nemmeno il fatto che effettua automaticamente il login dell'utente. Inoltre non sembra accettare un parametro per sopprimere questa funzionalità. Per i miei scopi basterebbe un semplice booleano.
AGGIORNAMENTO: Ho dovuto scegliere una singola risposta, ma c'erano molte informazioni utili in diverse altre risposte che cercherò di riassumere brevemente qui...
ESISTE una funzione che fa esattamente quello che stavo cercando di fare:
wp_authenticate($username, $password)
TUTTAVIA, ha un inconveniente. Imposterà automaticamente i cookie di login che possono creare problemi in una situazione come la mia. Quindi fate attenzione. Questa funzione non è attualmente nel codex.La scelta migliore per quello che sto facendo è
wp_authenticate_username_password($user, $username, $password)
perché NON imposta i cookie di login. Questa funzione è più documentata, ma il dettaglio VERAMENTE importante che non era nel codex è che puoi passareNULL
come primo parametro. Questo significa che puoi effettivamente usarla per fare esattamente comewp_authenticate()
senza preoccuparti che i cookie vengano compromessi. Leggi la documentazione per non farti confondere dalla risposta. Restituisce un oggetto WP_User oppure un WP_Error (non un booleano!).

C'è una funzione nei user.php
dei file core chiamata wp_authenticate_username_password
che sembra essere ciò che stai cercando.
Se vuoi evitare di passare l'oggetto $user
(probabilmente hai solo username + password), allora passa semplicemente null
come primo argomento della funzione:
$check = wp_authenticate_username_password( NULL, 'nome_utente', '#lapassword' );
Puoi poi verificare facilmente il risultato con is_wp_error( $check )
.

Questo non fa quello che sembra. È un errore comune (che ho fatto anche io). Però ho appena scoperto una funzione che fa esattamente quello che vogliamo! Vedi la mia risposta...

@kaiser "Eh". Non avevo mai realizzato che si potesse passare NULL come primo parametro. Buono a sapersi. Dai anche un'occhiata a wp_authenticate()
(vedi la mia risposta). L'ho trovato dopo settimane di ricerche.

Utilizza,
e
Spiegazione
// ottieni l'utente tramite login usando lo username fornito (input del form)
$user = get_user_by('login', $username);
// assegna l'ID dell'utente basato sul nome di login
$user_id = $user->ID;
// ottieni i dati dell'utente passando la variabile $user_id a get_userdata
// che restituisce l'oggetto utente e una serie di informazioni correlate all'utente da accedere
$user_data = get_userdata($user_id);
// assegna lo username e la password a delle variabili
$user_login = $user_data->user_login;
$user_pass = $user_data->user_pass;
// verifica lo username/password rispetto ai valori inviati dall'input
if ($user_login = $username && $user_pass = $password) {
// fai qualcosa...
Note
$username
dovrebbe validare true di default altrimenti un oggetto utente non sarebbe stato restituito se lo$username
fornito non corrispondeva a uno già esistente nel database. Pertanto la validazione dipende quindi dalla variabile$password
che memorizza l'input del form fornito dall'utente.Potrebbe esserci un modo più efficiente per ottenere questo risultato, sia accorciando il codice esistente sia utilizzando altre funzioni dell'API.
AGGIORNAMENTO
Basandoti sul suggerimento di fdsa potresti a tua volta usare wp_authenticate_username_password
in questo modo,
$auth = wp_authenticate_username_password($user, $username, $password);
if (!$auth->user_login = $username && !$auth->user_pass = $password) {
echo 'non autenticato';
} else {
echo 'autenticato';
}
Ma ancora meglio,
$auth = wp_authenticate_username_password($user, $username, $password);
if (is_wp_error($auth)) {
echo 'non autenticato';
} else {
echo 'autenticato';
}
In realtà il credito/risposta migliore dovrebbe essere dato a fdsa per il metodo più efficiente tramite una (purtroppo) funzione core di WP non documentata.

Disclaimer: Questa risposta è solo per mostrare cosa succede dietro le quinte e non vuole essere un esempio reale su come fare le cose.
Backtrace
wp_signon()
chiama wp_set_auth_cookie()
, che a sua volta chiama wp_generate_auth_cookie()
. Il risultato verrà utilizzato all'interno di setcookie()
come 2nd argomento.
(Non performante) divertimento con i filtri
alias ingannare WordPress nel modo sbagliato.
Potresti quindi intervenire nel filtro 'auth_cookie'
all'interno di wp_generate_auth_cookie()
e semplicemente impostarlo a null o a qualcos'altro rispetto ai valori SECURE_AUTH_COOKIE
o AUTH_COOKIE
. Questo ti lascerà con un cookie inutile, che non può effettuare il login.

"Ecco qui": wp_authenticate($username, $password)
Non è documentato nel codex, ma puoi cercarlo su wpseek.
Fa esattamente quello che sembra. Prende un nome utente e una password in testo semplice e restituisce un oggetto WP_User
oppure un WP_Error
... e NON effettua il login di nessuno.
Attenzione! Il seguente codice restituirà SEMPRE true (perché la funzione restituisce comunque un oggetto):
$auth = ( wp_authenticate($username, $password) ) ? TRUE : FALSE;
Probabilmente vorrai fare qualcosa del genere:
$test_creds = wp_authenticate($username, $pass);
$class = get_class($test_creds);
$auth = ( $class == 'WP_User' ) ? TRUE : FALSE;
Spero che questo sia utile a qualcuno.

Puoi usare instanceof
o is_a()
per verificare WP_User
. Potresti anche semplicemente usare una delle funzioni sopra citate e rimuovere il filtro su authenticate
...

Consiglio di usare is_wp_error($auth)
che restituirà TRUE
se l'autenticazione fallisce e FALSE
se l'autenticazione ha successo.

Un'altra nota: Questo non ti farà accedere, ma ti lascerà comunque il cookie impostato, poiché la funzione chiama il filtro `'authenticate`. Se opti per questa soluzione, dovresti assicurarti con certezza che tutte le callback del filtro siano rimosse. Altrimenti il cielo potrebbe caderti sulla testa :)

È bene saperlo. Anche wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' );
ha lo stesso problema? Puoi approfondire leggermente sul "cielo che cade"? Cosa andrà storto?

Nota: Invece di usare wp_authenticate
dovresti effettivamente usare user_pass_ok($user_login, $user_pass)
che a sua volta utilizza wp_authenticate
essendo la funzione wrapper corretta che restituisce true/false
. Tuttavia, come ha detto @kaiser, il cookie viene impostato tramite il filtro authenticate
. La funzione wp_authenticate_username_password
invece non sembra impostare il cookie.

Secondo la documentazione, wp_authenticate()
EFFETTIVAMENTE effettua il login dell'utente se le credenziali sono corrette. Stranamente per me non funziona.
