Как проверить пользователя от ouside wordpress / php?

9

Я работаю над приложением ajax, которое будет встроено в страницу WordPress. Приложение ajax обменивается данными с сервлетами, работающими на tomcat. Теперь сервлетам нужен способ определить, приходит ли запрос от пользователя, который вошел в WordPress. И если пользователь вошел в систему, сервлеты также должны быть в состоянии определить идентификатор пользователя, чтобы иметь возможность запрашивать базу данных. Если пользователь не вошел в систему, запрос будет отклонен.

Другими словами, мне нужно разрешить сервлету выполнять запрос, только если пользователь, вызвавший запрос, вошел в WordPress (версия 3.3.x). И сервлет (tomcat), и wordpress (apache2) работают на одной физической машине и совместно используют одну и ту же базу данных.

Теоретически это можно легко решить, выполнив следующее:

  1. Во время входа в WordPress некоторые пользовательские токены сохраняются в переменной javascript.
  2. Приложение ajax перенаправляет токен пользователя сервлетам при каждом вызове.
  3. Сервлеты используют токен для запроса WordPress, если он действителен (т. Е. Если пользователь вошел в систему), и выполняют или отклоняют запрос.

Вопрос в том, как это можно реализовать на стороне WordPress?
Потому что то, что делает теорию настолько сложной, это то, что я еще не занимался программированием на php.

Сначала я подумал о том, чтобы передать cookie-файл wordpress_logged_in (auth) сервлету и позволить сервлету запрашивать wordpress, если cookie-файл auth все еще действителен. Но, как кажется, это невозможно сделать, так как wp_validate_auth_cookie () всегда терпит неудачу, даже если передаются cookie-данные вошедшего в систему пользователя. Другое решение может заключаться в разработке плагина, который хранит идентификатор сеанса и идентификатор пользователя в таблице, к которой легко могут быть запрошены сервлеты. Или, может быть, есть другое решение ...

Давос Сиворт
источник
Почему бы не написать или не использовать плагин, который предлагает аутентификацию пользователя как сервис AJAX? Он может использовать весь стек WP, и любое приложение может использовать его, выполнив подходящий HTTP-запрос. Позаботьтесь о том, чтобы защитить свои учетные данные соответствующим образом.
Рафаэль
Я думаю, что я неправильно выразил свое мнение, мне не нужна служба аутентификации ajax. Мне нужен способ, позволяющий сервлету проверять уже аутентифицированного пользователя. Т.е. проверить, если пользователь все еще вошел в систему. Дело в следующем: пользователь входит в систему, получает доступ к приложению Ajax, которое связывается с сервлетом для хранения / извлечения данных. Теперь сервлету нужен какой-то способ 1) проверить, поступает ли запрос от вошедшего в систему пользователя и 2) извлечь идентификатор пользователя (для дальнейшего доступа к базе данных).
Давос Сиворт
Возможно, вам следует отредактировать свой вопрос, чтобы включить все эти комментарии. Желательно представить свою проблему (!) И понять, в чем заключается ваша идея. В частности, дайте четкое пошаговое описание процесса, который вы себе представляете.
Рафаэль
Я надеюсь, что вопрос теперь более ясен.
Давос Сиворт
как ты это сделал? не могли бы вы поделиться своим решением? Вы использовали XMLRPC?
pkyeck

Ответы:

7

WordPress уже имеет API, встроенный через сервер XMLRPC. Это означает, что вы можете сделать запрос XMLRPC из вашего Java-приложения и проверить имя пользователя / пароль. К сожалению, нет способа просто пройти аутентификацию через него как есть.

Тем не менее, это очень легко свернуть свой собственный. Просто подключите xmlrpc_methodsфильтр и добавьте свой. Ключ массива, который вы добавляете, будет методом xmlrpc, который вы вызываете из своего приложения, а значением будет функция, которая вызывается сервером 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;
}

И функция обратного вызова wpse39662_check_loginполучит один аргумент, массив вещей, отправленных на сервер 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;
}

Вот все это как плагин . С этим установленным и включенным XMLRPC на вашем сайте WP вы сможете отправлять запросы с помощью некоторого клиента XMLRPC (я уверен, что в Java он есть).

Вот код, который я использовал для проверки выше (клиент Python XMLRPC).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
chrisguitarguy
источник
1
Спасибо! Это приносит мне огромный шаг вперед! Можно ли добиться того же самого с помощью файла cookie для аутентификации пользователей? Так что мне не нужно хранить и отправлять имя пользователя / pwd по проводам? Мой проект состоит из приложения ajax, встроенного в страницу WordPress. Приложение ajax вызывает сервлет, а сервлет спрашивает WordPress, аутентифицирован ли пользователь. Я мог бы передать user / pwd в приложение ajax и передать его сервлету, но я боюсь, что это не очень безопасно. Поэтому я попытался передать содержимое куки-файла auth в wp_validate_auth_cookie (), но он всегда терпит неудачу.
Давос Сиворт
Я просто сгенерировал бы токен или что-то для пользователя и сохранил бы его на обоих концах системы. Затем передайте токен вперед и назад.
chrisguitarguy
2

Wordpress (в настоящее время) проверяет, вошел ли пользователь в систему, проверив один из файлов cookie, которые он выдает при входе в систему. Он создает содержимое этого файла cookie путем некоторого хеширования. Подробности в функции "wp_generate_auth_cookie" в /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);
}

Вы можете заново создать этот алгоритм (используя эту и другие функции auth_cookie) в своем коде Java, чтобы выполнить те же проверки. JS может быть использован, чтобы убедиться, что куки отправляются на ваш сервлет.

В противном случае XMLRPC может быть хорошей идеей. Вы можете написать новый метод (как объяснено в другом решении здесь) для проверки подлинности cookie (вместо проверки имени пользователя и пароля, как это обычно делается).

laughingbovine
источник
2

Получите плагин Exec-PHP , а затем создайте страницу WordPress (а не пост) с хорошей permalink ( http://mysite/user_id/) и кодом в get_current_user_id()справочнике по 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.'.';
}
?>

Затем вы можете извлечь куки, которые клиент отправляет вам, и поместить их в GETзапрос http://127.0.0.1/user_id/. Тогда вы узнаете, вошел ли пользователь в систему и какой у него идентификатор пользователя.

Олате
источник
1

Вы могли бы сделать что-то вроде этого на страницах без 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
}

?>
FlashingCursor
источник
Спасибо за ответ, проблема в том, что сервлеты написаны на Java, поэтому PHP-код не может быть выполнен. То, что я ищу, это какой-то внешний интерфейс, который позволяет сервлету / Java общаться с WordPress / PHP. Конечно, есть какой-то интерфейс, я просто не могу его найти ...
Давос Сиворт
Ах я вижу. Возможно, использование чего-то вроде Quercus caucho.com/resin-3.0/quercus поможет вам получить лучшее из обоих миров?
FlashingCursor
Спасибо, но quercus - неправильное решение, так как у меня уже есть работающая установка wordpress / php / apache и работающая установка servlet / java / tomcat. Теперь единственное, что мне нужно, это интерфейс между этими двумя, который позволяет сервлету проверять, вошел ли пользователь в wordpress (какой-то интерфейс / protocoll / ipc / что угодно).
Давос Сиворт
1

Это плагин WordPress с одним файлом, который делает работу:

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

По сути, он предоставляет новый метод XML-RPC, с помощью которого вы можете попросить WordPress проверить wordpress_logged_in_...cookie.

Затем вам нужно написать некоторый код для запроса этого метода и передать ему значение wordpress_logged_in_...cookie.

Этот метод возвращает либо false(если cookie не проверяется), либо идентификатор пользователя, если проверка прошла успешно.

kYuZz
источник