Cum să validezi un utilizator din afara WordPress/php?

21 ian. 2012, 15:32:29
Vizualizări: 17.5K
Voturi: 10

Lucrez la o aplicație AJAX care va fi integrată într-o pagină WordPress. Aplicația AJAC schimbă date cu servlete rulează pe Tomcat. Acum servletele au nevoie de o metodă pentru a determina dacă o cerere vine de la un utilizator autentificat în WordPress. Dacă utilizatorul este logat, servletele trebuie să poată determina ID-ul utilizatorului pentru a interoga baza de date. Dacă utilizatorul nu este logat, cererea va fi respinsă.

Cu alte cuvinte, am nevoie ca un servlet să execute o cerere doar dacă utilizatorul care a inițiat cererea este autentificat în WordPress (versiunea 3.3.x). Atât servletele (Tomcat) cât și WordPress (Apache2) rulează pe aceeași mașină fizică și folosesc aceeași bază de date.

Teoretic, aceasta ar putea fi rezolvată ușor în felul următor:

  1. În timpul autentificării în WordPress, un token de utilizator este stocat într-o variabilă JavaScript.
  2. Aplicația AJAC transmite tokenul utilizatorului către servlete la fiecare apel.
  3. Servletele folosesc tokenul pentru a interoga WordPress dacă este valid (adică dacă utilizatorul este logat) și execută sau resping cererea.

Întrebarea este cum poate fi implementat acest lucru pe partea de WordPress?
Problema care face teoria complicată este faptul că nu am făcut încă programare PHP.

La început m-am gândit să transmit cookie-ul wordpress_logged_in (auth) către servlet și să las servletul să interogheze WordPress dacă cookie-ul auth este încă valid. Dar se pare că acest lucru nu poate fi făcut, deoarece wp_validate_auth_cookie() întotdeauna eșuează, chiar dacă sunt transmise datele cookie ale unui utilizator logat. O altă soluție ar putea fi dezvoltarea unui plugin care să stocheze sessionid-ul și userid-ul într-un tabel, care ar putea fi ușor interogat de servlete. Sau poate există o altă soluție...

5
Comentarii

De ce să nu scrii sau să folosești un plugin care oferă autentificarea utilizatorului ca serviciu AJAX? Acesta ar putea folosi întregul stack WP, iar orice aplicație ar putea să-l utilizeze prin trimiterea unei cereri HTTP adecvate. Asigură-te însă că protejezi corespunzător credentialele utilizatorilor tăi.

Raphael Raphael
21 ian. 2012 19:00:48

Cred că m-am exprimat greșit, nu am nevoie de un serviciu de autentificare AJAX. Ceea ce am nevoie este o modalitate de a permite unui servlet să valideze un utilizator deja autentificat. Adică să verifice dacă utilizatorul este încă logat. Ideea este următoarea: Utilizatorul se autentifică, accesează o aplicație AJAX, care comunică cu servlet-ul pentru a stoca/prelua date. Acum servlet-ul are nevoie de o modalitate de a 1) testa dacă cererea provine de la un utilizator logat și 2) prelua ID-ul utilizatorului (pentru accesul ulterior la baza de date).

Davos Seaworth Davos Seaworth
21 ian. 2012 23:05:46

Poate ar trebui să editezi întrebarea ta pentru a incorpora toate aceste comentarii. De preferință, prezintă-ți problema (!) și care este ideea ta. În special, oferă o descriere clară pas cu pas a procesului pe care îl imaginezi.

Raphael Raphael
22 ian. 2012 00:33:20

Sper că întrebarea este acum mai clară.

Davos Seaworth Davos Seaworth
22 ian. 2012 01:30:46

cum ai reușit să o faci? poți să împărtășești soluția ta? ai folosit XMLRPC?

Philipp Kyeck Philipp Kyeck
20 apr. 2012 13:33:22
Toate răspunsurile la întrebare 5
2

WordPress are deja un API integrat prin intermediul unui server XMLRPC. Acest lucru înseamnă că poți face o cerere XMLRPC din aplicația ta Java și să verifici un nume de utilizator/parolă. Din păcate, nu există o modalitate de a autentifica direct prin aceasta în starea sa actuală.

Totuși, este foarte ușor să implementezi propria soluție. Pur și simplu conectează-te la filtrul xmlrpc_methods și adaugă-ți metoda. Cheia din array pe care o adaugi va fi metoda XMLRPC pe care o apelezi din aplicația ta, iar valoarea va fi funcția apelată de serverul XMLRPC al WordPress.

<?php
add_filter('xmlrpc_methods', 'wpse39662_add_login_method' );
/**
 * Filtrează metodele XMLRPC pentru a permite doar verificarea numelui de utilizator/parolă
 * pentru un anumit utilizator
 */
function wpse39662_add_login_method( $methods )
{
    $methods['wpse39662.login'] = 'wpse39662_check_login';
    return $methods;
}

Iar funcția de callback, wpse39662_check_login, va primi un singur argument, array-ul de date trimise către serverul XMLRPC.

<?php
function wpse39662_check_login( $args )
{
    $username = $args[0];
    $password = $args[1];

    $user = wp_authenticate( $username, $password );

    if( is_wp_error( $user ) )
    {
        return false;
    }
    return true;
}

Poți găsi toate acestea ca un plugin. Cu acesta instalat și XMLRPC activat pe site-ul tău WordPress, ar trebui să poți face cereri folosind un client XMLRPC (sigur Java are unul).

Iată codul pe care l-am folosit pentru a testa funcționalitatea de mai sus (client XMLRPC în Python).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
21 ian. 2012 18:54:30
Comentarii

Mulțumesc! Asta mă aduce cu un pas uriaș înainte! Poate fi realizat același lucru folosind cookie-ul de autentificare al utilizatorului? Ca să nu fie nevoie să stochez și să trimit numele de utilizator/parola prin rețea? Proiectul meu constă într-o aplicație AJAX care este integrată într-o pagină WordPress. Aplicația AJAX apelează un servlet, iar servletul întreabă WordPress dacă utilizatorul este autentificat. Aș putea să transmit numele de utilizator/parola către aplicația AJAX și să le transfer către servlet, dar mă tem că nu ar fi foarte sigur. Așa că am încercat să transmit conținutul cookie-ului de autentificare la wp_validate_auth_cookie(), dar întotdeauna eșuează.

Davos Seaworth Davos Seaworth
21 ian. 2012 20:39:42

Aș genera pur și simplu un token sau ceva similar pentru utilizator și l-aș stoca pe ambele părți ale sistemului. Apoi aș trimite token-ul înainte și înapoi.

chrisguitarguy chrisguitarguy
22 ian. 2012 05:31:27
0

WordPress (în prezent) verifică dacă utilizatorul este încă autentificat prin verificarea unuia dintre cookie-urile pe care le generează la logare. Conținutul acestui cookie este construit prin intermediul unor operații de hashing. Detaliile se găsesc în funcția "wp_generate_auth_cookie" din /wp-includes/pluggable.php:

function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') {
    $user = get_userdata($user_id);

    $pass_frag = substr($user->user_pass, 8, 4);

    $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);
    $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);

    $cookie = $user->user_login . '|' . $expiration . '|' . $hash;

    return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
}

Puteți recrea acest algoritm (folosind această funcție și alte funcții auth_cookie) în codul vostru Java pentru a face aceleași verificări. JS ar putea fi folosit pentru a vă asigura că cookie-ul este trimis către servlet-ul vostru.

Alternativ, XMLRPC ar putea fi o idee bună. Ați putea scrie o nouă metodă (așa cum este explicat într-o altă soluție de aici) pentru a valida cookie-ul de autentificare (în loc să validați numele de utilizator și parola, așa cum se face de obicei).

25 iul. 2012 19:23:10
0

Obțineți modulul Exec-PHP, apoi creați o pagină WordPress (nu un articol) cu un permalink frumos (http://mysite/user_id/) și codul din get_current_user_id() referința API:

<?php
$user_id = get_current_user_id();
if ($user_id == 0) {
    echo 'În prezent nu ești autentificat.';
} else {
    echo 'Ești autentificat ca utilizator '.$user_id.'.';
}
?>

Apoi puteți extrage cookie-urile pe care clientul vi le trimite și să le includeți într-o cerere GET pentru http://127.0.0.1/user_id/. Astfel veți ști dacă utilizatorul este autentificat și care este ID-ul său de utilizator.

16 iun. 2013 00:18:48
3

Puteți face ceva de genul acesta pe paginile care nu sunt WordPress:

<?php
require('./wp-blog-header.php');
// Asigurați-vă că ^ indică rădăcina instalării dvs. WordPress

if ( is_user_logged_in() ) {
   // Executați cererea dvs. aici
}

?>
21 ian. 2012 16:49:47
Comentarii

Mulțumesc pentru răspuns, problema este că servletele sunt scrise în Java, deci codul PHP nu poate fi executat. Ceea ce caut eu este un fel de interfață externă care să permită unei servlete/Java să comunice cu WordPress/PHP. Cu siguranță există o astfel de interfață disponibilă, dar nu reușesc să o găsesc...

Davos Seaworth Davos Seaworth
21 ian. 2012 17:01:52

Ah, am înțeles. Poate utilizarea a ceva precum Quercus http://www.caucho.com/resin-3.0/quercus/ ar putea să-ți ofere cele mai bune din ambele lumi?

FlashingCursor FlashingCursor
21 ian. 2012 17:11:54

Mulțumesc, dar Quercus nu este soluția potrivită, deoarece deja am o instalație funcțională WordPress/PHP/Apache și o instalație funcțională servlet/Java/Tomcat. Singurul lucru de care am nevoie acum este o interfață între aceste două, care să permită servletului să verifice dacă un utilizator este autentificat în WordPress (o interfață/protocol/IPC/orice altceva).

Davos Seaworth Davos Seaworth
21 ian. 2012 18:04:45
0

Acesta este un plugin WordPress într-un singur fișier care își face treaba:

function yournamespace_validateAuthCookie($cookie, $scheme = 'logged_in') {
    return wp_validate_auth_cookie($cookie, $scheme);
}

function yournamespace_new_xmlrpc_methods($methods) {
    $methods['yournamespace.validateAuthCookie'] = 'yournamespace_validateAuthCookie';
    return $methods;
}
add_filter('xmlrpc_methods', 'yournamespace_new_xmlrpc_methods');

Practic, expune o nouă metodă XML-RPC prin care poți cere WordPress să valideze cookie-ul wordpress_logged_in_....

Apoi, va trebui să scrii niște cod pentru a interoga această metodă și pentru a-i transmite valoarea cookie-ului wordpress_logged_in_....

Această metodă va returna fie false (dacă cookie-ul nu este valid) fie ID-ul utilizatorului dacă validarea reușește.

4 mar. 2015 22:13:59