Cum să verifici username/parola fără a autentifica utilizatorul

9 aug. 2012, 18:39:28
Vizualizări: 25.7K
Voturi: 6

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...

  1. 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.

  2. 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 transmite NULL ca primul parametru. Acest lucru înseamnă că o poți folosi efectiv pentru a face exact ca wp_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!).

4
Comentarii

Codex este condus de utilizatori. Pur și simplu autentifică-te și modifică/editează/adaugă ceea ce consideri că lipsește. (Privește-l ca pe Wikipedia).

kaiser kaiser
9 aug. 2012 19:55:26

Notă: wp_authenticate nu setează efectiv cookie-urile de autentificare, asta se întâmplă în wp_signon. Totuși, wp_authenticate va aplica toate metodele de autentificare conectate, deci dacă un cookie de autentificare valid este trimis împreună cu cererea, atunci poate valida utilizatorul indiferent de numele de utilizator/parolă. Dacă vrei doar să verifici numele de utilizator și parola, wp_authenticate_username_password este într-adevăr corect.

Otto Otto
14 aug. 2012 00:52:06

ai lansat vreodată acest plugin/endpoint?

lofidevops lofidevops
25 oct. 2017 01:02:20

@d3vid Acesta a fost pentru un proiect privat de acum câțiva ani, așa că codul ar trebui actualizat pentru a fi compatibil cu WP actual. Dar dacă ești interesat de acest lucru, trimite-mi un email.

emersonthis emersonthis
25 oct. 2017 01:35:08
Toate răspunsurile la întrebare 4
4
10

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 ).

9 aug. 2012 19:15:15
Comentarii

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...

emersonthis emersonthis
9 aug. 2012 19:54:24

+1 pare să fie soluția perfectă. Sper că nu te superi pentru editare.

kaiser kaiser
9 aug. 2012 19:54:29

@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.

emersonthis emersonthis
9 aug. 2012 20:03:58

Cu siguranță cea mai eficientă metodă.

Adam Adam
9 aug. 2012 20:04:20
1

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.

http://wpseek.com/wp_authenticate_username_password/

9 aug. 2012 19:12:55
Comentarii

Aceasta este minunat. Dar get_userdata va returna parola hash-uită (nu cea în clar). Aveți vreun sfat cum să ocolim acest lucru?

emersonthis emersonthis
9 aug. 2012 19:33:47
0

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.

9 aug. 2012 20:15:30
6

"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.

9 aug. 2012 19:59:08
Comentarii

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...

kaiser kaiser
9 aug. 2012 20:03:17

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

Adam Adam
9 aug. 2012 20:07:56

Î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 :)

kaiser kaiser
9 aug. 2012 20:20:21

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?

emersonthis emersonthis
9 aug. 2012 20:56:20

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.

Adam Adam
9 aug. 2012 21:02:33

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

Gerald Schneider Gerald Schneider
25 iul. 2013 10:16:01
Arată celelalte 1 comentarii