問題描述

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