Jak zweryfikować użytkownika z ouside wordpress / php?


9

Pracuję nad aplikacją ajax, która zostanie osadzona na stronie wordpress. Aplikacja ajax wymienia dane z serwletami działającymi na tomcat. Teraz serwlety potrzebują sposobu, aby ustalić, czy żądanie pochodzi od użytkownika zalogowanego do wordpress. A jeśli użytkownik jest zalogowany, serwlety muszą także być w stanie określić identyfikator użytkownika, aby móc wysłać zapytanie do bazy danych. Jeśli użytkownik nie jest zalogowany, żądanie zostanie odrzucone.

Innymi słowy, muszę pozwolić serwletowi wykonać żądanie tylko wtedy, gdy użytkownik, który spowodował żądanie, jest zalogowany w wordpress (wersja 3.3.x). Zarówno serwlet (tomcat), jak i wordpress (apache2) działają na tej samej maszynie fizycznej i współużytkują tę samą bazę danych.

Teoretycznie można to łatwo rozwiązać, wykonując następujące czynności:

  1. Podczas logowania wordpressa token użytkownika jest przechowywany w zmiennej javascript.
  2. Aplikacja ajax przekazuje token użytkownika do serwletów przy każdym wywołaniu.
  3. Serwlety używają tokena do zapytania o wordpress, jeśli jest on prawidłowy (tj. Jeśli użytkownik jest zalogowany) i wykonania lub odrzucenia żądania.

Pytanie brzmi, jak można to zaimplementować po stronie wordpress?
Ponieważ to, co czyni teorię tak skomplikowaną, to fakt, że nie zrobiłem jeszcze żadnego programowania php.

Najpierw myślałem o przesłaniu ciasteczka wordpress_logged_in (auth) do serwletu i pozwoliłem, aby serwlet zapytał o słowo, jeśli plik cookie auth jest nadal ważny. Ale jak się wydaje, nie można tego zrobić, ponieważ wp_validate_auth_cookie () zawsze kończy się niepowodzeniem, nawet jeśli przekazywane są dane cookie zalogowanego użytkownika. Innym rozwiązaniem może być opracowanie wtyczki przechowującej identyfikator sesji i identyfikator użytkownika w tabeli, do której aplety mogłyby łatwo zapytać. A może istnieje inne rozwiązanie ...


Dlaczego nie napisać ani nie skorzystać z wtyczki, która oferuje uwierzytelnianie użytkowników jako usługa AJAX? Może korzystać z całego stosu WP i każda aplikacja może z niego korzystać, wysyłając odpowiednie żądanie HTTP. Należy jednak odpowiednio chronić dane uwierzytelniające użytkownika.
Raphael

Myślę, że źle mnie wyraziłem, nie potrzebuję usługi uwierzytelniania ajax. Potrzebuję sposobu, aby umożliwić serwletowi sprawdzenie poprawności już uwierzytelnionego użytkownika. Tzn. Sprawdź, czy użytkownik jest nadal zalogowany. Chodzi o to: użytkownik loguje się, uzyskuje dostęp do aplikacji ajax, która komunikuje się z serwletem w celu przechowywania / pobierania danych. Teraz serwlet potrzebuje sposobu na 1) sprawdzenie, czy żądanie pochodzi od zalogowanego użytkownika i 2) pobranie identyfikatora użytkownika (w celu uzyskania dalszego dostępu do bazy danych).
Davos Seaworth

Może powinieneś edytować swoje pytanie, aby uwzględnić wszystkie te komentarze. Najlepiej przedstaw swój problem (!) I swój pomysł. W szczególności podaj jasny krok po kroku opisany proces.
Raphael

Mam nadzieję, że pytanie jest teraz bardziej jasne.
Davos Seaworth,

jak to zrobiłeś? czy możesz podzielić się swoim rozwiązaniem? korzystałeś z XMLRPC?
pkyeck

Odpowiedzi:


7

WordPress ma już wbudowany interfejs API za pośrednictwem serwera XMLRPC. Oznacza to, że możesz wykonać żądanie XMLRPC z aplikacji Java i zweryfikować nazwę użytkownika / hasło. Niestety, nie ma sposobu, aby uwierzytelnić się za pomocą tego, co jest.

To powiedziawszy, bardzo łatwo jest rzucić własny. Wystarczy podłączyć xmlrpc_methodsfiltr i dodać swój. Klucz tablicy, który dodajesz, to metoda xmlrpc wywoływana z aplikacji, a wartością będzie funkcja wywoływana przez serwer WordPress XMLRPC.

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

A funkcja zwrotna wpse39662_check_loginotrzyma jeden argument, tablicę rzeczy wysłaną do serwera 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;
}

Oto wszystko jako wtyczka . Po zainstalowaniu i włączeniu XMLRPC w witrynie WP, możesz być w stanie wysyłać żądania za pomocą klienta XMLRPC (jestem pewien, że Java go ma).

Oto kod, którego użyłem do przetestowania powyższego (klient Python XMLRPC).

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

1
Dziękuję Ci! To daje mi ogromny krok dalej! Czy to samo można osiągnąć za pomocą pliku cookie uwierzytelniania użytkowników? Więc nie muszę przechowywać i wysyłać nazwy użytkownika / pwd przez drut? Mój projekt składa się z aplikacji ajaxowej osadzonej na stronie wordpress. Aplikacja ajax wywołuje serwlet, a serwlet pyta wordpress, czy użytkownik jest uwierzytelniony. Mógłbym przekazać użytkownika / pwd do aplikacji ajax i przenieść go do serwletu, ale obawiam się, że nie byłoby to zbyt bezpieczne. Próbowałem więc przekazać zawartość auth cookie do wp_validate_auth_cookie (), ale zawsze kończy się to niepowodzeniem.
Davos Seaworth

Wygenerowałbym token lub coś dla użytkownika i zapisałbym go na obu końcach systemu. Następnie przekaż token tam iz powrotem.
chrisguitarguy

2

Wordpress (obecnie) sprawdza, czy użytkownik jest nadal zalogowany, sprawdzając jeden z plików cookie, które podaje podczas logowania. Konstruuje zawartość tego pliku cookie, wykonując pewne haszowanie. Szczegóły znajdują się w funkcji „wp_generate_auth_cookie” w /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);
}

Możesz ponownie utworzyć ten algorytm (używając tej i innych funkcji auth_cookie) w kodzie Java, aby wykonać te same kontrole. JS może być wykorzystany do upewnienia się, że plik cookie zostanie przesłany do twojego serwletu.

W przeciwnym razie dobrym pomysłem może być XMLRPC. Możesz napisać nową metodę (jak wyjaśniono w innym rozwiązaniu tutaj), aby sprawdzić poprawność pliku cookie uwierzytelniania (zamiast sprawdzania poprawności nazwy użytkownika i hasła, jak to zwykle bywa).


2

Pobierz wtyczkę Exec-PHP , a następnie utwórz stronę WordPress (nie post) z ładnym permalink ( http://mysite/user_id/) i kodem w get_current_user_id()interfejsie 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.'.';
}
?>

Następnie możesz wyodrębnić pliki cookie, które klient wysyła do ciebie, i złożyć je w GETżądaniu http://127.0.0.1/user_id/. Wtedy będziesz wiedział, czy użytkownik jest zalogowany i jaki jest jego identyfikator użytkownika.


1

Możesz zrobić coś takiego na stronach innych niż 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
}

?>

Dzięki za odpowiedź, problem polega na tym, że serwlety są napisane w Javie, więc nie można wykonać kodu php. To, czego szukam, to jakiś zewnętrzny interfejs, który pozwala serwletowi / java komunikować się z wordpress / php. Z pewnością jest jakiś dostępny interfejs, po prostu nie mogę go znaleźć ...
Davos Seaworth,

O, rozumiem. Być może użycie czegoś takiego jak Quercus caucho.com/resin-3.0/quercus może dać ci to, co najlepsze z obu światów?
FlashingCursor

Dziękuję, ale Quercus jest złym rozwiązaniem, ponieważ mam już działającą instalację wordpress / php / apache i działającą instalację serwletu / java / tomcat. Teraz jedyne, czego potrzebuję, to interfejs między tymi dwoma, który pozwala serwletowi sprawdzić, czy użytkownik jest zalogowany do WordPressa (jakiś interfejs / protokół / ipc / cokolwiek).
Davos Seaworth

1

To jest jednoplikowa wtyczka WordPress, która wykonuje zadanie:

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

Zasadniczo ujawnia nową metodę XML-RPC, za pomocą której można poprosić WordPress o sprawdzenie poprawności wordpress_logged_in_...pliku cookie.

Następnie musisz napisać kod, aby wysłać zapytanie do tej metody i przekazać jej wartość wordpress_logged_in_...pliku cookie.

Ta metoda zwróci albo false(jeśli plik cookie nie zostanie sprawdzony), albo identyfikator użytkownika, jeśli sprawdzenie się powiedzie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.