Cum să verifici username/parola fără a autentifica utilizatorul
Scriu un plugin care creează un endpoint API pentru validarea perechilor username/parolă.
În prezent folosesc wp_signon()
pentru a verifica dacă combinația username/parolă funcționează. Funcționează bine când credențialele sunt incorecte deoarece returnează un obiect de eroare. Dar când credențialele sunt corecte, autentifică automat acel utilizator, astfel încât endpoint-ul meu returnează o pagină întreagă.
Codexul momentan nici măcar nu menționează faptul că autentifică automat utilizatorul. De asemenea, nu pare să accepte un parametru pentru a suprima această funcționalitate. Pentru scopurile mele, un simplu boolean ar fi suficient.
ACTUALIZARE: A trebuit să aleg un singur răspuns, dar au existat multe informații utile în celelalte răspunsuri pe care voi încerca să le rezum pe scurt aici...
EXISTĂ o funcție care face exact ce încercam eu să fac:
wp_authenticate($username, $password)
TOTUȘI, vine cu un dezavantaj. Va seta automat cookie-urile de autentificare care pot crea probleme într-o situație ca a mea. Așa că aveți grijă. Această funcție nu este momentan în codex.Cea mai bună alegere pentru ceea ce fac eu este
wp_authenticate_username_password($user, $username, $password)
deoarece NU setează cookie-urile de autentificare. Această funcție este mai bine documentată, dar detaliul FOARTE important care nu era în codex este că poți transmiteNULL
ca primul parametru. Acest lucru înseamnă că o poți folosi efectiv pentru a face exact cawp_authenticate()
fără să-ți faci griji că cookie-urile se vor strica. Citește documentația pentru a nu fi confuz în privința răspunsului. Returnează fie un obiect WP_User fie un WP_Error (nu un boolean!).

Există o funcție în fișierul user.php
din fișierele de bază numită wp_authenticate_username_password
care pare a fi ceea ce cauți.
Dacă dorești să eviți să transmiți obiectul $user
(probabil ai doar numele de utilizator + parola), atunci trimite null
ca prim argument al funcției:
$check = wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' );
Apoi poți verifica simplu rezultatul cu is_wp_error( $check )
.

Acest lucru nu face ceea ce sună a face. Este o greșeală comună (pe care am făcut-o și eu). Totuși, tocmai am descoperit o funcție care face exact ceea ce ne dorim! Vezi răspunsul meu...

@kaiser "Hmm". Nu am realizat niciodată că poți folosi NULL ca prim parametru. Asta e bine de știut. Verifică și wp_authenticate()
(vezi răspunsul meu). Am găsit-o abia după săptămâni de căutări.

Folosește,
și
Explicație
// obține utilizatorul după login prin numele de utilizator furnizat (input din formular)
$user = get_user_by('login', $username);
// atribuie ID-ul de utilizator pe baza numelui de login
$user_id = $user->ID;
// obține datele utilizatorului prin transmiterea variabilei $user_id către get_userdata
// care returnează obiectul utilizator și o serie de informații legate de utilizator pentru acces
$user_data = get_userdata($user_id);
// atribuie numele de utilizator și parola variabilelor
$user_login = $user_data->user_login;
$user_pass = $user_data->user_pass;
// verifică numele de utilizator/parola față de valorile introduse în formular
if ($user_login = $username && $user_pass = $password) {
// fă ceva...
Note
$username
ar trebui să fie validat implicit ca adevărat, altfel un obiect utilizator nu ar fi fost returnat dacă$username
furnizat nu se potrivește cu unul existent în baza de date. Prin urmare, validarea atunci depinde de variabila$password
care stochează input-ul din formular furnizat de utilizator.Poate exista o metodă mai eficientă pentru a realiza acest lucru, fie prin scurtarea codului existent, fie prin utilizarea altor funcții API.
ACTUALIZARE
Bazat pe sugestia lui fdsa, ai putea folosi wp_authenticate_username_password
în acest mod,
$auth = wp_authenticate_username_password($user, $username, $password);
if (!$auth->user_login = $username && !$auth->user_pass = $password) {
echo 'neautentificat';
} else {
echo 'autentificat';
}
Dar chiar mai bine decât atât,
$auth = wp_authenticate_username_password($user, $username, $password);
if (is_wp_error($auth)) {
echo 'neautentificat';
} else {
echo 'autentificat';
}
Într-adevăr, creditul/răspunsul marcat ar trebui să fie acordat lui fdsa pentru cea mai eficientă metodă prin intermediul (din păcate) a unei funcții nedocumentate din nucleul WP.

Declinare de responsabilitate: Acest răspuns ar trebui doar să arate ce se întâmplă în spatele scenei și nu este menit să fie un exemplu real despre cum să faci lucrurile.
Backtrace
wp_signon()
apelează wp_set_auth_cookie()
, care la rândul său apelează wp_generate_auth_cookie()
. Rezultatul va fi folosit în interiorul setcookie()
ca al 2lea argument.
(Non-performant) distracție cu filtre
a.k.a. înșelând WordPress într-un mod greșit.
Apoi ai putea să intervii în filtrul 'auth_cookie'
din interiorul wp_generate_auth_cookie()
și să-l setezi pur și simplu la null sau la altceva decât valoarea SECURE_AUTH_COOKIE
sau AUTH_COOKIE
. Acest lucru te va lăsa cu un cookie fără sens, care nu poate efectua autentificarea.

"Ta-da": wp_authenticate($username, $password)
Nu este documentat în codex deloc, dar îl poți căuta pe wpseek.
Face exact ceea ce sugerează. Primește un nume de utilizator și o parolă în text simplu și returnează fie un obiect WP_User
fie un WP_Error
... și NU autentifică pe nimeni.
Un avertisment important! Următorul cod va returna ÎNTOTDEAUNA true (deoarece funcția returnează un obiect în orice caz):
$auth = ( wp_authenticate($username, $password) ) ? TRUE : FALSE;
Probabil vei dori să faci ceva de genul acesta:
$test_creds = wp_authenticate($username, $pass) ;
$class = get_class($test_creds);
$auth = ( $class == 'WP_User' ) ? TRUE : FALSE ;
Sper că acest lucru îi va fi de folos cuiva.

Poți folosi instanceof
sau is_a()
pentru a verifica dacă este WP_User
. De asemenea, poți pur și simplu să folosești una din funcțiile de mai sus și să elimini filtrul de pe authenticate
...

Recomand să folosești is_wp_error($auth)
care va returna TRUE
dacă autentificarea eșuează și FALSE
dacă trece de autentificare.

Încă o observație: Aceasta nu te va loga, dar totuși va lăsa cookie-ul setat, deoarece funcția apelează filtrul `'authenticate`. Dacă alegi această soluție, ar trebui să te asiguri că toate callback-urile filtrului sunt eliminate. Altfel, cerul ar putea să-ți cadă în cap :)

E bine de știut. Funcția wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' );
are aceeași problemă? Poți să elaborezi puțin despre "cerul care se prăbușește"? Ce anume se va întâmpla?

Notă: În loc să folosești wp_authenticate
, ar fi mai bine să utilizezi user_pass_ok($user_login, $user_pass)
, care la rândul ei folosește wp_authenticate
ca funcție wrapper corectă și returnează true/false
. Totuși, după cum a menționat @kaiser, cookie-ul este setat prin filtrul authenticate
. Funcția wp_authenticate_username_password
nu pare să seteze cookie-ul.

Conform documentației, wp_authenticate()
ÎNTRA-ADEVĂR autentifică utilizatorul dacă credentialele sunt corecte. În mod ciudat, la mine nu funcționează așa.
