Как проверить пользователя вне WordPress/PHP?

21 янв. 2012 г., 15:32:29
Просмотры: 17.5K
Голосов: 10

Я работаю над AJAX-приложением, которое будет встроено в страницу WordPress. Приложение обменивается данными с сервлетами, работающими на Tomcat. Сервлетам необходимо определить, приходит ли запрос от пользователя, авторизованного в WordPress, и получить его ID для запросов к базе данных. Если пользователь не авторизован, запрос должен быть отклонен.

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

Теоретически это можно реализовать следующим образом:

  1. При авторизации в WordPress некий токен пользователя сохраняется в JavaScript-переменной.
  2. AJAX-приложение передает этот токен сервлетам при каждом запросе.
  3. Сервлеты проверяют валидность токена (т.е. факт авторизации пользователя) и выполняют или отклоняют запрос.

Вопрос: как это можно реализовать на стороне WordPress?
Сложность в том, что у меня пока нет опыта программирования на PHP.

Первоначально я думал о передаче куки wordpress_logged_in (auth) сервлету и проверке его валидности через WordPress, но функция wp_validate_auth_cookie() всегда возвращает ошибку, даже при передаче данных авторизованного пользователя.

Другой вариант - создать плагин, который будет сохранять sessionid и userid в таблицу, доступную для запросов сервлетов. Или, возможно, есть другие решения...

5
Комментарии

Почему бы не написать или использовать плагин, который предоставляет аутентификацию пользователей как AJAX-сервис? Он может использовать весь стек WP, и любое приложение сможет обращаться к нему, отправляя соответствующий HTTP-запрос. Однако убедитесь, что должным образом защищаете учетные данные пользователей.

Raphael Raphael
21 янв. 2012 г. 19:00:48

Думаю, я выразился не совсем точно — мне не нужен AJAX-сервис аутентификации. Мне нужен способ, позволяющий сервлету проверить уже аутентифицированного пользователя. То есть, убедиться, что пользователь всё ещё в системе. Суть в следующем: пользователь входит в систему, получает доступ к AJAX-приложению, которое общается с сервлетом для сохранения/получения данных. Теперь сервлету нужен способ: 1) проверить, что запрос пришёл от авторизованного пользователя, и 2) получить его ID (для дальнейшего доступа к базе данных).

Davos Seaworth Davos Seaworth
21 янв. 2012 г. 23:05:46

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

Raphael Raphael
22 янв. 2012 г. 00:33:20

Надеюсь, теперь вопрос стал понятнее.

Davos Seaworth Davos Seaworth
22 янв. 2012 г. 01:30:46

как ты в итоге решил эту задачу? можешь поделиться своим решением? ты использовал XMLRPC?

Philipp Kyeck Philipp Kyeck
20 апр. 2012 г. 13:33:22
Все ответы на вопрос 5
2

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

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

<?php
add_filter('xmlrpc_methods', 'wpse39662_add_login_method' );
/**
 * Фильтрует методы XMLRPC, чтобы позволить проверять только логин/пароль
 * для заданного пользователя
 */
function wpse39662_add_login_method( $methods )
{
    $methods['wpse39662.login'] = 'wpse39662_check_login';
    return $methods;
}

И callback-функция 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 на вашем сайте WordPress, вы сможете делать запросы с помощью любого XMLRPC клиента (уверен, в Java такой есть).

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

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
21 янв. 2012 г. 18:54:30
Комментарии

Спасибо! Это значительно продвигает меня вперед! Можно ли достичь того же, используя аутентификационную cookie пользователя? Чтобы не хранить и не передавать логин/пароль по сети? Мой проект представляет собой ajax-приложение, встроенное в страницу WordPress. Ajax-приложение вызывает сервлет, а сервлет проверяет в WordPress, аутентифицирован ли пользователь. Я мог бы передать логин/пароль в ajax-приложение и отправить его в сервлет, но боюсь, что это не очень безопасно. Поэтому я попытался передать содержимое аутентификационной cookie в wp_validate_auth_cookie(), но это всегда завершается ошибкой.

Davos Seaworth Davos Seaworth
21 янв. 2012 г. 20:39:42

Я бы просто сгенерировал токен или что-то подобное для пользователя и сохранил его на обеих сторонах системы. Затем передавал бы этот токен туда и обратно.

chrisguitarguy chrisguitarguy
22 янв. 2012 г. 05:31:27
0

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-коде для выполнения аналогичных проверок. Для передачи cookie в ваш сервлет можно использовать JavaScript.

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

25 июл. 2012 г. 19:23:10
0

Установите плагин Exec-PHP, затем создайте страницу в WordPress (не запись) с удобным постоянным адресом (http://mysite/user_id/) и разместите код из справочника по API get_current_user_id():

<?php
$user_id = get_current_user_id();
if ($user_id == 0) {
    echo 'Вы не авторизованы.';
} else {
    echo 'Вы авторизованы как пользователь '.$user_id.'.';
}
?>

Затем вы можете извлечь cookies, отправленные клиентом, и передать их в GET-запросе на http://127.0.0.1/user_id/. Это позволит вам определить, авторизован ли пользователь и узнать его ID.

16 июн. 2013 г. 00:18:48
3

Вы можете сделать что-то подобное на страницах, не относящихся к WordPress:

<?php
require('./wp-blog-header.php');
// Убедитесь, что ^ указывает на корень вашей установки WP

if ( is_user_logged_in() ) {
   // Выполните ваш запрос здесь
}

?>
21 янв. 2012 г. 16:49:47
Комментарии

Спасибо за ответ. Проблема в том, что сервлеты написаны на Java, поэтому PHP-код не может быть выполнен. Мне нужно что-то вроде внешнего интерфейса, который позволит сервлету/Java общаться с WordPress/PHP. Наверняка есть какой-то интерфейс, просто я не могу его найти...

Davos Seaworth Davos Seaworth
21 янв. 2012 г. 17:01:52

А, понятно. Возможно, использование чего-то вроде Quercus http://www.caucho.com/resin-3.0/quercus/ даст вам лучшее из обоих миров?

FlashingCursor FlashingCursor
21 янв. 2012 г. 17:11:54

Спасибо, но Quercus — это не то решение, так как у меня уже работают WordPress/PHP/Apache и сервлет/Java/Tomcat. Теперь мне нужен только интерфейс между этими двумя системами, который позволит сервлету проверять, авторизован ли пользователь в WordPress (какой-то интерфейс/протокол/межпроцессное взаимодействие/что угодно).

Davos Seaworth Davos Seaworth
21 янв. 2012 г. 18:04:45
0

Это одностраничный плагин для 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_....

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

Метод вернет либо false (если куки не прошли проверку), либо ID пользователя в случае успешной валидации.

4 мар. 2015 г. 22:13:59