問題描述

我正在使用一個嵌入在 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。