Wie validiere ich einen Benutzer von ouside wordpress / php?

9

Ich arbeite an einer Ajax-Anwendung, die in eine WordPress-Seite eingebettet wird. Die Ajax-App tauscht Daten mit Servlets aus, die auf Tomcat ausgeführt werden. Jetzt benötigen die Servlets eine Möglichkeit, um festzustellen, ob eine Anforderung von einem Benutzer stammt, der bei WordPress angemeldet ist. Wenn der Benutzer angemeldet ist, müssen die Servlets auch die Benutzer-ID ermitteln können, um die Datenbank abfragen zu können. Wenn der Benutzer nicht angemeldet ist, wird die Anforderung abgelehnt.

Mit anderen Worten, ich muss ein Servlet nur dann eine Anforderung ausführen lassen, wenn der Benutzer, der die Anforderung verursacht hat, bei WordPress (Version 3.3.x) angemeldet ist. Sowohl das Servlet (Tomcat) als auch WordPress (Apache2) werden auf demselben physischen Computer ausgeführt und verwenden dieselbe Datenbank.

Theoretisch könnte dies leicht durch Folgendes gelöst werden:

  1. Während der WordPress-Anmeldung wird ein Benutzertoken in einer Javascript-Variablen gespeichert.
  2. Die Ajax-App leitet das Benutzertoken bei jedem Aufruf an die Servlets weiter.
  3. Die Servlets verwenden das Token, um WordPress abzufragen, ob es gültig ist (dh wenn der Benutzer angemeldet ist) und die Anforderung auszuführen oder abzulehnen.

Die Frage ist, wie dies auf der WordPress-Seite umgesetzt werden kann.
Denn was die Theorie so kompliziert macht, ist die Tatsache, dass ich noch keine PHP-Programmierung durchgeführt habe.

Zuerst dachte ich daran, das Cookie wordpress_logged_in (auth) an das Servlet zu übertragen und das Servlet WordPress abfragen zu lassen, wenn das Cookie auth noch gültig ist. Dies scheint jedoch nicht möglich zu sein, da wp_validate_auth_cookie () immer fehlschlägt, selbst wenn Cookie-Daten eines angemeldeten Benutzers übergeben werden. Eine andere Lösung könnte darin bestehen, ein Plugin zu entwickeln, das die Sitzungs- und Benutzer-ID in einer Tabelle speichert, die von den Servlets leicht abgefragt werden kann. Oder vielleicht gibt es eine andere Lösung ...

Davos Seaworth
quelle
Warum nicht ein Plugin schreiben oder verwenden , das Benutzerauthentifizierung als AJAX-Dienst bietet? Es könnte den gesamten WP-Stack verwenden, und jede Anwendung könnte ihn verwenden, indem sie eine geeignete HTTP-Anforderung ausgibt. Achten Sie jedoch darauf, die Anmeldeinformationen Ihres Benutzers angemessen zu schützen.
Raphael
Ich glaube, ich habe mich falsch ausgedrückt, ich brauche keinen Ajax-Authentifizierungsdienst. Was ich brauche, ist eine Möglichkeit, einem Servlet zu ermöglichen, einen bereits authentifizierten Benutzer zu validieren. Dh überprüfen, ob der Benutzer noch angemeldet ist. Der Punkt ist folgender: Der Benutzer meldet sich an und greift auf eine Ajax-App zu, die mit dem Servlet kommuniziert, um Daten zu speichern / abzurufen. Jetzt benötigt das Servlet eine Möglichkeit, 1) zu testen, ob die Anforderung von einem angemeldeten Benutzer stammt, und 2) die Benutzer-ID abzurufen (für den weiteren Datenbankzugriff).
Davos Seaworth
Vielleicht sollten Sie Ihre Frage bearbeiten, um all diese Kommentare aufzunehmen. Präsentieren Sie vorzugsweise Ihr Problem (!) Und Ihre Idee. Geben Sie insbesondere Schritt für Schritt eine klare Beschreibung des von Ihnen geplanten Prozesses.
Raphael
Ich hoffe, die Frage ist jetzt klarer.
Davos Seaworth
Wie bist du dazu gekommen? Könnten Sie Ihre Lösung teilen? Hast du XMLRPC benutzt?
Pkyeck

Antworten:

7

In WordPress ist bereits eine API über einen XMLRPC-Server integriert. Das heißt, Sie können eine XMLRPC-Anfrage von Ihrer Java-App aus stellen und einen Benutzernamen / ein Passwort überprüfen. Leider gibt es keine Möglichkeit, sich einfach so zu authentifizieren, wie es ist.

Das heißt, es ist sehr einfach, Ihre eigenen zu rollen. Schließen Sie einfach xmlrpc_methodseinen Filter an und fügen Sie Ihren hinzu. Der Array-Schlüssel, den Sie hinzufügen, ist die xmlrpc-Methode, die Sie von Ihrer App aus aufrufen, und der Wert ist die Funktion, die vom WordPress-XMLRPC-Server aufgerufen wird.

<?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;
}

Und die Rückruffunktion wpse39662_check_loginwürde ein Argument erhalten, das Array von Dingen, die an den XMLRPC-Server gesendet werden.

<?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;
}

Hier ist alles als Plugin . Wenn dies installiert und XMLRPC auf Ihrer WP-Site aktiviert ist, sollten Sie in der Lage sein, Anforderungen mit einem XMLRPC-Client zu stellen (ich bin sicher, Java hat einen).

Hier ist der Code, mit dem ich das Obige getestet habe (Python XMLRPC-Client).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
chrisguitarguy
quelle
1
Danke! Das bringt mich einen großen Schritt weiter! Kann das gleiche mit dem Auth-Cookie des Benutzers erreicht werden? Also muss ich den Benutzernamen / pwd nicht speichern und über das Kabel senden? Mein Projekt besteht aus einer Ajax-App, die in eine WordPress-Seite eingebettet ist. Die Ajax-App ruft ein Servlet auf und das Servlet fragt WordPress, ob der Benutzer authentifiziert ist. Ich könnte den Benutzer / pwd an die Ajax-App übergeben und an das Servlet übertragen, aber ich fürchte, das wäre nicht sehr sicher. Also habe ich versucht, den Inhalt des Auth-Cookies an wp_validate_auth_cookie () zu übergeben, aber es schlägt immer fehl.
Davos Seaworth
Ich würde einfach ein Token oder etwas für den Benutzer generieren und es an beiden Enden des Systems speichern. Dann geben Sie den Token hin und her.
Chrisguitarguy
2

Wordpress überprüft (derzeit), ob der Benutzer noch angemeldet ist, indem es eines der Cookies überprüft, die es beim Anmelden ausgibt. Der Inhalt dieses Cookies wird durch Hashing erstellt. Die Details finden Sie in der Funktion "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);
}

Sie können diesen Algorithmus (mit dieser und den anderen auth_cookie-Funktionen) in Ihrem Java-Code neu erstellen, um dieselben Überprüfungen durchzuführen. JS kann verwendet werden, um sicherzustellen, dass das Cookie an Ihr Servlet gesendet wird.

Andernfalls ist XMLRPC möglicherweise eine gute Idee. Sie können eine neue Methode schreiben (wie in einer anderen Lösung hier erläutert), um das Auth-Cookie zu validieren (anstatt Benutzername und Passwort zu validieren, wie dies normalerweise der Fall ist).

Lachbinder
quelle
2

Holen Sie sich das Exec-PHP-Pluginhttp://mysite/user_id/ und erstellen Sie eine WordPress-Seite (kein Beitrag) mit einem schönen Permalink ( ) und dem Code in der get_current_user_id()API-Referenz :

<?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.'.';
}
?>

Sie können dann die Cookies extrahieren, die der Kunde Ihnen sendet, und sie in eine GETAnfrage für stellen http://127.0.0.1/user_id/. Dann wissen Sie, ob der Benutzer angemeldet ist und wie seine Benutzer-ID lautet.

Olathe
quelle
1

Auf den Nicht-WP-Seiten können Sie so etwas tun:

<?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
}

?>
FlashingCursor
quelle
Vielen Dank für die Antwort, das Problem ist, Servlets sind in Java geschrieben, so dass PHP-Code nicht ausgeführt werden kann. Was ich suche, ist eine Art externe Schnittstelle, über die ein Servlet / Java mit WordPress / PHP kommunizieren kann. Es gibt sicherlich eine Art Schnittstelle zur Verfügung, ich kann es einfach nicht finden ...
Davos Seaworth
Ah ich sehe. Vielleicht bringt Ihnen die Verwendung von Quercus caucho.com/resin-3.0/quercus das Beste aus beiden Welten?
FlashingCursor
Vielen Dank, aber Quercus ist die falsche Lösung, da ich bereits eine funktionierende WordPress / PHP / Apache- und eine funktionierende Servlet / Java / Tomcat-Installation habe. Jetzt brauche ich nur noch eine Schnittstelle zwischen diesen beiden, mit der das Servlet überprüfen kann, ob ein Benutzer bei WordPress angemeldet ist (einige Schnittstellen / Protokolle / IPCs / was auch immer).
Davos Seaworth
1

Dies ist ein WordPress-Plugin mit einer Datei, das die Aufgabe erledigt:

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

Grundsätzlich wird eine neue XML-RPC-Methode verfügbar gemacht, mit der Sie WordPress bitten können, das wordpress_logged_in_...Cookie zu validieren .

Sie müssen dann Code schreiben, um diese Methode abzufragen und den Wert des wordpress_logged_in_...Cookies zu übergeben.

Diese Methode gibt entweder false(wenn das Cookie nicht validiert wird) oder die Benutzer-ID zurück, wenn die Validierung erfolgreich ist.

kYuZz
quelle