问题描述

我正在使用一个嵌入在 wordpress 页面中的 ajax 应用程序。 ajax 应用程序与在 tomcat 上运行的 servlet 交换数据。现在,servlet 需要一种方法来确定请求是否来自登录到 wordpress 的用户。并且如果用户登录,则 servlet 还必须能够确定用户 id 才能查询数据库。如果用户没有登录,该请求将被拒绝。

所以换句话说,只有引起请求的用户登录到 wordpress(版本 3.3.x),我才需要让 servlet 执行请求。两者,servlet(tomcat) 和 wordpress(apache2) 在同一物理机上运行并共享相同的数据库。

在理论上,这可以很容易地通过做以下操作来解决:

  1. 在 wordpress 登录期间,一些用户令牌存储在 javascript 变量中。

  2. ajax 应用程序在每次调用时将用户令牌转发到 servlet 。

  3. servlet 使用令牌来查询 wordpress 是否有效 (即,如果用户登录) 并执行或拒绝该请求。

问题是如何在 wordpress 方面实现?因为什么使理论如此复杂的事实,我还没有做任何 PHP 程序设计。

首先,我正在考虑将 wordpress_logged_in(auth)cookie 发送到 servlet,并让 servlet 查询 wordpress,如果 auth cookie 仍然有效。但是,似乎这样做是不可能的,因为即使通过登录用户的 cookie-data, wp_validate_auth_cookie() 总是失败。另一个解决方案可能是开发一个将 sessionid 和 userid 存储在表中的插件,可以很容易地被 servlet 查询。或者也许有另外一个解决方案

最佳解决方法

WordPress 已经通过 XMLRPC 服务器内置了一个 API 。意思是,您可以从您的 java 应用程序生成 XMLRPC 请求,并验证用户名/密码。不幸的是,没有办法通过它进行身份验证。

也就是说,滚动自己很容易。只需挂入 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;
}

这里是所有的 as a plugin 。在 WP 站点启用了这个安装和 XMLRPC 后,您应该可以使用一些 XMLRPC 客户端 (我确定 Java 有一个) 请求。

以下是用于测试上述代码 (Python XMLRPC 客户端) 的代码。

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

次佳解决方法

WordPress(当前) 检查用户是否仍然登录,方法是检查登录后给出的其中一个 cookie 。它通过做一些哈希来构建这个 cookie 的内容。详细信息请参见/wp-includes/pluggable.php 中的”wp_generate_auth_cookie” 功能:

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

您可以在 Java 代码中使用 re-create 这个算法 (使用这个和其他 auth_cookie 函数) 进行相同的检查。可以使用 JS 来确保将 cookie 发送到您的 servlet 。

否则,XMLRPC 可能是一个好主意。你可以编写一个新的方法 (如另一个解决方案在这里解释) 验证 auth cookie(而不是验证用户名和密码,通常是完成的) 。

第三种解决方法

获取 Exec-PHP plugin,然后使用一个很好的固定链接 (http://mysite/user_id/) 和 get_current_user_id() API 参考的代码制作一个 WordPress 页面 (而不是一篇文章):

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

然后,您可以提取客户端发送给您的 Cookie,并将其放在 GET http://127.0.0.1/user_id/请求中。然后你会知道用户是否登录了他们的用户 ID 。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。