従来のWP Adminダッシュボード内から使用することを意図したプラグインの一部として単純なAjax関数を開発していますが、ログインCookieの状態に関して矛盾が生じています。
問題、TL; DRバージョン
私のAjax呼び出しの出力は常にログアウトしたユーザーのコンテキストで実行されます。具体的には、PHPサイドのget_current_user_id()
がページ自体の出力に正しいログインユーザーID番号を返すにもかかわらず、var_dump(get_current_user_id())
はすべてのAjax起動呼び出しに対して0
を返します。
document.cookie
をチェックすることはJS側でログインクッキーの不在を確認するようですが、var_dump($_COOKIE)
は正しいログインクッキーの存在を示します。
さらに奇妙なことに、Firefoxのネットワークペインには、ログイン値とともにAjax呼び出しからWordPressに送信されている完全なCookieが表示されます。
何ができる?
コードとコンテキスト
特定のWP管理ダッシュボードページがロードされると、私のJSは単純にWP-API(v2)で特定の投稿に対するコメントをポーリングします。ポーリング方法は次のようになります。
/**
* Checks for any new comments.
*/
var pollForNewComments = function () {
var url = api_base + '/comments&post=' + getPostId() + '&offset=' + getCommentCount();
console.log(document.cookie);
jQuery.get(url, function (response) {
if (response.length) {
appendComments(response);
showNewCommentsNotice();
}
});
};
console.log(document.cookie)
への呼び出しに注意してください。このメソッドが実行されると、コンソールログの出力に次の出力が表示されます。
wordpress_test_cookie=WP+Cookie+check; wp-settings-time-10=1456479389; popunder=yes; popundr=yes; setover18=1
ログインクッキーがないことに注意してください。
ただし、同じ呼び出しの場合、Firefoxネットワークペインには、HTTPリクエストヘッダーに存在するログインクッキーしたが表示されます。
ログインクッキーがWordPressによって受信されていることを確認するために、私はプラグインコードでvar_dump(get_current_user_id()); var_dump($_COOKIE); exit();
という些細なことを実行します。
int(0)
array(3) {
["wordpress_test_cookie"]=>
string(15) "WP Cookie check"
["wordpress_logged_in_9416a7b43bd88dae58cf6c88b9f89f3f"]=>
string(130) "athirduser|1456650402|a23GIhs43jJ651dKkCEKfX6EKjfnTCpT76k6Hgvznls|5da91c9c365cf214c486b0a32333a78fb6394385e5bcad619666511330322bda"
["wp-settings-time-10"]=>
string(10) "1456479389"
}
Ajax以外の呼び出しの出力は正しく返され、ログインCookieが存在することと正しいユーザーIDが返されることの両方が示されます。
Ajaxと非Ajaxの違いがここにあるのはなぜですか。 console.log(document.cookie)
とFirefoxがNetwork Inspectorに表示するものとの違いは何ですか?
これは単一サーバーのセットアップ、ローカル開発環境、notクロスドメインリクエストです。
ありがとう。
私はこれを修正するためにWordPressコアとREST APIプラグインコードをトレースしなければなりませんでしたが、ついにそれを行いました。 解はここで説明されています 。
このソリューションのTL; DRは、正しい値が_wpnonce
HTTP GET
パラメータ(クエリ文字列内)に指定されていない限り、WP-APIがログインCookieの内容を無視し、認証されていない(ログアウト)要求を想定するというものです。 HTTP_X_WP_NONCE
HTTPヘッダー。私のJavaScriptはこれを正しく含んでいませんでした。修正されたJavaScriptメソッドは次のようになります。
/**
* Checks for any new comments.
*/
var pollForNewComments = function () {
var url = api_base + '/comments&post=' + getPostId() + '&offset=' + getCommentCount()
+ '&_wpnonce=' + wpApiSettings.nonce;
jQuery.get(url, function (response) {
if (response.length) {
appendComments(response);
showNewCommentsNotice();
}
});
};
_wpnonce
グローバルJavaScript変数(REST APIプラグインによって追加される)を使用してクエリ文字列にwpApiSettings.nonce
パラメータを追加すると問題が解決することに注意してください。