1

I'm developing a simple Ajax function as part of a plugin intended to be used from within the traditional WP Admin dashboard but am encountering a discrepancy regarding the login cookie state.

The problem, TL;DR version

The output of my Ajax calls always runs in the context of a logged-out user. Specifically, get_current_user_id() returns 0 for all Ajax-initiated calls, despite a PHP-side var_dump(get_current_user_id()) returning the correct logged-in user ID number on the output of the page itself.

Checking document.cookie seems to confirm the absence of a login cookie on the JS side, but a var_dump($_COOKIE) shows the correct login cookie's presence.

To add to the weirdness, Firefox's Network Pane shows the full cookie, along with the login value, being sent to WordPress from the Ajax call.

What gives?

Code & context

When a certain WP admin dashboard page is loaded, my JS simply polls the WP-API (v2) for comments on a given post. The polling method looks like this:

/**
 * 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();
        }
    });
};

Note the call to console.log(document.cookie). When this method runs, the output of the console log shows this output:

wordpress_test_cookie=WP+Cookie+check; wp-settings-time-10=1456479389; popunder=yes; popundr=yes; setover18=1

Notice there is no login cookie.

However, for the same call, the Firefox Network Pane shows the login cookie does exist in the HTTP request headers:

Firefox Network Panel screenshot shows login cookie, even though earlier console.log() call does not???

To verify that the login cookie is being received by WordPress, I execute a trivial var_dump(get_current_user_id()); var_dump($_COOKIE); exit(); in my plugin code, and the output for the Ajax call confirms that, despite the login cookie's presence, WordPress thinks there is no logged in user:

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"
}

The output of non-Ajax calls return correctly, showing both a login cookie is present and the correct user ID returned.

Why the discrepancy between Ajax and non-Ajax calls here? Why the difference between console.log(document.cookie) and what Firefox shows in its Network Inspector?

This is a single-server setup, a local development environment, not a cross-domain request.

Thanks.

  • 1
    Can you show us how you registered your AJAX function? – fischi Feb 26 '16 at 10:04
1

I had to trace through WordPress core and the REST API plugin code to fix this, but finally did it. The solution is described here.

The TL;DR of the solution is that the WP-API will ignore the content of the login cookie and assume an unauthenticated (logged out) request unless the correct value is given in the _wpnonce HTTP GET parameter (in the query string) or the HTTP_X_WP_NONCE HTTP header. My JavaScript did not correctly include this. The corrected JavaScript method looks like this:

/**     
 * 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();
        }
    });
};

Note that adding the _wpnonce parameter in the query string with the wpApiSettings.nonce global JavaScript variable (which is added by the REST API plugin) fixes the issue for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.