Come convalidare un utente da ouside wordpress / php?


9

Sto lavorando a un'applicazione Ajax che verrà incorporata in una pagina di wordpress. L'app ajax scambia dati con servlet in esecuzione su Tomcat. Ora i servlet hanno bisogno di un modo per determinare se una richiesta proviene da un utente che ha effettuato l'accesso a wordpress. E se l'utente ha effettuato l'accesso, anche i servlet devono essere in grado di determinare l'id utente per poter interrogare il database. Se l'utente non lo ha registrato, la richiesta verrà rifiutata.

Quindi, in altre parole, devo consentire a un servlet di eseguire una richiesta solo se l'utente che ha causato la richiesta ha effettuato l'accesso a wordpress (versione 3.3.x). Entrambi, servlet (tomcat) e wordpress (apache2) vengono eseguiti sulla stessa macchina fisica e condividono lo stesso database.

In teoria questo potrebbe essere facilmente risolto nel modo seguente:

  1. Durante l'accesso a wordpress, alcuni token utente vengono archiviati in una variabile javascript.
  2. L'app ajax inoltra l'utente token ai servlet ad ogni chiamata.
  3. I servlet usano il token per interrogare wordpress se è valido (cioè se l'utente ha effettuato l'accesso) ed eseguire o rifiutare la richiesta.

La domanda è: come può essere implementato sul lato wordpress?
Perché, ciò che rende la teoria così complicata è il fatto che non ho ancora fatto alcuna programmazione PHP.

Per prima cosa stavo pensando di trasmettere il cookie wordpress_logged_in (auth) al servlet e lasciare che il servlet interroghi wordpress se il cookie di autenticazione è ancora valido. Ma a quanto pare, questo non può essere fatto, poiché wp_validate_auth_cookie () fallisce sempre, anche se i dati dei cookie di un utente connesso vengono passati. Un'altra soluzione potrebbe essere quella di sviluppare un plug-in che memorizzi sessionid e userid in una tabella, che potrebbe essere facilmente interrogata dai servlet. O forse c'è un'altra soluzione ...


Perché non scrivere o utilizzare un plug-in che offre l'autenticazione utente come servizio AJAX? Potrebbe utilizzare l'intero stack WP e qualsiasi applicazione potrebbe utilizzarlo emettendo una richiesta HTTP adatta. Tuttavia, fai attenzione a proteggere le credenziali dell'utente in modo adeguato.
Raphael,

Penso di avermi espresso male, non ho bisogno di un servizio di autenticazione Ajax. Ciò di cui ho bisogno è un modo per consentire a un servlet di convalidare un utente già autenticato. Vale a dire se l'utente è ancora connesso. Il punto è questo: l'utente accede, accede a un'app Ajax, che comunica al servlet per archiviare / recuperare i dati. Ora il servlet ha bisogno di un modo per 1) verificare se la richiesta proviene da un utente connesso e 2) recuperare l'id utente (per un ulteriore accesso al database).
Davos Seaworth,

Forse dovresti modificare la tua domanda per incorporare tutti quei commenti. Preferibilmente, presenta il tuo problema (!) E qual è la tua idea. In particolare, fornisci una chiara descrizione dettagliata del processo che prevedi.
Raffaello,

Spero che la domanda sia più chiara ora.
Davos Seaworth,

come sei finito a farlo? potresti condividere la tua soluzione? hai usato XMLRPC?
becco

Risposte:


7

WordPress ha già un'API integrata tramite un server XMLRPC. Ciò significa che è possibile effettuare una richiesta XMLRPC dall'app java e verificare un nome utente / password. Sfortunatamente, non c'è modo di autenticarsi così com'è.

Detto questo, è molto facile creare il tuo. Basta agganciare xmlrpc_methods, un filtro e aggiungere il tuo. La chiave dell'array con cui aggiungi sarà il metodo xmlrpc che chiami dalla tua app e il valore sarà la funzione che viene chiamata dal server XMLRPC di WordPress.

<?php
add_filter('xmlrpc_methods', 'wpse39662_add_login_method' );
/**
 * Filters the XMLRPC methods to allow just checking the login/pass of
 * a given users
 */
function wpse39662_add_login_method( $methods )
{
    $methods['wpse39662.login'] = 'wpse39662_check_login';
    return $methods;
}

E la funzione di callback wpse39662_check_login, gli farebbe passare un argomento, l'array di cose inviato al server 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;
}

Ecco tutto questo come plugin . Con quello installato e XMLRPC abilitato sul tuo sito WP, dovresti essere in grado di effettuare richieste con alcuni client XMLRPC (sono sicuro che Java ne abbia uno).

Ecco il codice che ho usato per testare quanto sopra (client XMLRPC Python).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True

1
Grazie! Questo mi porta un enorme passo avanti! Lo stesso può essere ottenuto utilizzando il cookie di autenticazione dell'utente? Quindi non devo archiviare e inviare il nome utente / pwd via cavo? Il mio progetto consiste in un'app Ajax incorporata in una pagina di wordpress. L'app ajax chiama un servlet e il servlet chiede a wordpress se l'utente è autenticato. Potrei passare l'utente / pwd all'app ajax e trasferirlo al servlet, ma temo che non sarebbe molto sicuro. Quindi ho provato a passare il contenuto del cookie di autenticazione a wp_validate_auth_cookie () ma fallisce sempre.
Davos Seaworth,

Genererei semplicemente un token o qualcosa per l'utente e lo memorizzerei su entrambe le estremità del sistema. Quindi passa il token avanti e indietro.
chrisguitarguy,

2

Wordpress (attualmente) controlla se l'utente è ancora connesso controllando uno dei cookie che emette al momento dell'accesso. Costruisce il contenuto di questo cookie facendo un po 'di hashing. I dettagli sono nella funzione "wp_generate_auth_cookie" in /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);
}

È possibile ricreare questo algoritmo (utilizzando questa e le altre funzioni auth_cookie) nel codice Java per effettuare gli stessi controlli. JS potrebbe essere usato per assicurarsi che il cookie venga inviato al tuo servlet.

Altrimenti XMLRPC potrebbe essere una buona idea. Potresti scrivere un nuovo metodo (come spiegato in un'altra soluzione qui) per convalidare il cookie di autenticazione (invece di convalidare nome utente e password come di solito viene fatto).


2

Ottieni il plug-in Exec-PHP , quindi crea una pagina WordPress (non un post) con un bel permalink ( http://mysite/user_id/) e il codice sul get_current_user_id()riferimento API :

<?php
$user_id = get_current_user_id();
if ($user_id == 0) {
    echo 'You are currently not logged in.';
} else {
    echo 'You are logged in as user '.$user_id.'.';
}
?>

È quindi possibile estrarre i cookie inviati dal client e inserirli in una GETrichiesta http://127.0.0.1/user_id/. Quindi saprai se l'utente ha effettuato l'accesso e qual è il suo ID utente.


1

Potresti fare qualcosa del genere nelle pagine non-wp:

<?php
require('./wp-blog-header.php');
// Make sure ^ points to the root of your WP installation

if ( is_user_logged_in() ) {
   // Perform your request here
}

?>

Grazie per la risposta, il problema è che i servlet sono scritti in Java, quindi il codice PHP non può essere eseguito. Quello che sto cercando è una sorta di interfaccia esterna che consenta a un servlet / java di comunicare con wordpress / php. C'è sicuramente un'interfaccia gentile disponibile, non riesco proprio a trovarlo ...
Davos Seaworth,

Ah, capisco. Forse usando qualcosa come Quercus caucho.com/resin-3.0/quercus potresti ottenere il meglio da entrambi i mondi?
Lampeggiante

Grazie, ma quercus è la soluzione sbagliata, poiché ho già un wordpress funzionante / php / apache e un'installazione servlet / java / tomcat funzionante. Ora l'unica cosa di cui ho bisogno è un'interfaccia tra quei due, che consenta al servlet di verificare se un utente è connesso a wordpress (qualche interfaccia / protocollo / ipc / qualunque).
Davos Seaworth,

1

Questo è un plugin WordPress a un file che fa il lavoro:

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');

In sostanza espone un nuovo metodo XML-RPC con il quale puoi chiedere a WordPress di convalidare il wordpress_logged_in_...cookie.

È quindi necessario scrivere del codice per interrogare questo metodo e passargli il valore del wordpress_logged_in_...cookie.

Questo metodo restituirà false(se il cookie non viene convalidato) o l'ID utente se la convalida ha esito positivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.