Skip to main content
Modify title to more represent what the issue was to make it easier to find later on
Link
ojrask
  • 185
  • 1
  • 10

wp-admin AJAX with Fetch API is done without user

added 55 characters in body
Source Link
ojrask
  • 185
  • 1
  • 10

TL;DR - Why is my user account not logged in during an AJAX request which is made inside wp-admin?


I have the following setup:

<?php

add_action('wp_ajax_foobar_action', 'foobar_action');
add_action('wp_ajax_nopriv_foobar_action', 'foobar_action');

function foobar_action() {
    check_ajax_referrer();

    wp_send_json((object) ['msg' => 'hello world']);
}

add_action('admin_print_scripts', function () {
    printf('<script type="text/javascript">window.custom_nonce = "%s";</script>', wp_create_nonce());
});

And in JS:

var msg = '';

// I'm using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
    },
    body: 'action=foobar_action&_wpnonce=' + window.custom_nonce
}).then(function (res) {
    msg = res.json().msg;
});

This is all run in wp-admin. The issue is that the wp-admin page/JS script itself is loaded as a logged in user, but the AJAX request that ends up into admin-ajax.php is done as a logged out guest user. This leads to the issue of wp-admin using nopriv and check_ajax_referrer failing 100% of the time.

Why does wp-admin make AJAX requests as a guest instead of the logged in user?

Currently, the AJAX endpoint returns 403 status with -1 content, as it should in case there is a nonce mismatch. If I comment out the check_ajax_referrer() call then the AJAX request runs through successfully. After some furious console.logging I've determined that the nonce values match in the JS fetch call and the AJAX endpoint that receives it (which means the nonce is properly transferred, but a wrong guest nonce is generated during the AJAX endpoint execution.

If I remove the wp_ajax_nopriv_foobar_action then WordPress doesn't find the auth-enabled AJAX action because there seemingly is no logged in user available (results in status 200 and body 0).

Steps I've attempted to fix the issue:

  • Logged out and in again, cleared caches/cookies, used incognito windows,
  • Restarted PHP-FPM, Nginx, object cache backends, MariaDB,
  • Disabled all plugins that are not required for operation,
  • Moved the AJAX hooking code around in my plugin code, all the way to the plugin root file (e.g. myplugin/myplugin.php),
  • Used GET instead of POST.

TL;DR - Why is my user account not logged in during an AJAX request which is made inside wp-admin?


I have the following setup:

<?php

add_action('wp_ajax_foobar_action', 'foobar_action');
add_action('wp_ajax_nopriv_foobar_action', 'foobar_action');

function foobar_action() {
    check_ajax_referrer();

    wp_send_json((object) ['msg' => 'hello world']);
}

add_action('admin_print_scripts', function () {
    printf('<script type="text/javascript">window.custom_nonce = "%s";</script>', wp_create_nonce());
});

And in JS:

var msg = '';

// I'm using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
    },
    body: 'action=foobar_action&_wpnonce=' + window.custom_nonce
}).then(function (res) {
    msg = res.json().msg;
});

This is all run in wp-admin. The issue is that the wp-admin page/JS script itself is loaded as a logged in user, but the AJAX request that ends up into admin-ajax.php is done as a logged out guest user. This leads to the issue of wp-admin using nopriv and check_ajax_referrer failing 100% of the time.

Why does wp-admin make AJAX requests as a guest instead of the logged in user?

Currently, the AJAX endpoint returns 403 status with -1 content, as it should in case there is a nonce mismatch. If I comment out the check_ajax_referrer() call then the AJAX request runs through successfully. After some furious console.logging I've determined that the nonce values match in the JS fetch call and the AJAX endpoint that receives it (which means the nonce is properly transferred, but a wrong guest nonce is generated during the AJAX endpoint execution.

If I remove the wp_ajax_nopriv_foobar_action then WordPress doesn't find the auth-enabled AJAX action because there seemingly is no logged in user available (results in status 200 and body 0).

Steps I've attempted to fix the issue:

  • Logged out and in again, used incognito windows,
  • Restarted PHP-FPM, Nginx, object cache backends, MariaDB,
  • Disabled all plugins that are not required for operation,
  • Moved the AJAX hooking code around in my plugin code, all the way to the plugin root file (e.g. myplugin/myplugin.php).

TL;DR - Why is my user account not logged in during an AJAX request which is made inside wp-admin?


I have the following setup:

<?php

add_action('wp_ajax_foobar_action', 'foobar_action');
add_action('wp_ajax_nopriv_foobar_action', 'foobar_action');

function foobar_action() {
    check_ajax_referrer();

    wp_send_json((object) ['msg' => 'hello world']);
}

add_action('admin_print_scripts', function () {
    printf('<script type="text/javascript">window.custom_nonce = "%s";</script>', wp_create_nonce());
});

And in JS:

var msg = '';

// I'm using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
    },
    body: 'action=foobar_action&_wpnonce=' + window.custom_nonce
}).then(function (res) {
    msg = res.json().msg;
});

This is all run in wp-admin. The issue is that the wp-admin page/JS script itself is loaded as a logged in user, but the AJAX request that ends up into admin-ajax.php is done as a logged out guest user. This leads to the issue of wp-admin using nopriv and check_ajax_referrer failing 100% of the time.

Why does wp-admin make AJAX requests as a guest instead of the logged in user?

Currently, the AJAX endpoint returns 403 status with -1 content, as it should in case there is a nonce mismatch. If I comment out the check_ajax_referrer() call then the AJAX request runs through successfully. After some furious console.logging I've determined that the nonce values match in the JS fetch call and the AJAX endpoint that receives it (which means the nonce is properly transferred, but a wrong guest nonce is generated during the AJAX endpoint execution.

If I remove the wp_ajax_nopriv_foobar_action then WordPress doesn't find the auth-enabled AJAX action because there seemingly is no logged in user available (results in status 200 and body 0).

Steps I've attempted to fix the issue:

  • Logged out and in again, cleared caches/cookies, used incognito windows,
  • Restarted PHP-FPM, Nginx, object cache backends, MariaDB,
  • Disabled all plugins that are not required for operation,
  • Moved the AJAX hooking code around in my plugin code, all the way to the plugin root file (e.g. myplugin/myplugin.php),
  • Used GET instead of POST.
Source Link
ojrask
  • 185
  • 1
  • 10

wp-admin AJAX is done without user

TL;DR - Why is my user account not logged in during an AJAX request which is made inside wp-admin?


I have the following setup:

<?php

add_action('wp_ajax_foobar_action', 'foobar_action');
add_action('wp_ajax_nopriv_foobar_action', 'foobar_action');

function foobar_action() {
    check_ajax_referrer();

    wp_send_json((object) ['msg' => 'hello world']);
}

add_action('admin_print_scripts', function () {
    printf('<script type="text/javascript">window.custom_nonce = "%s";</script>', wp_create_nonce());
});

And in JS:

var msg = '';

// I'm using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
    },
    body: 'action=foobar_action&_wpnonce=' + window.custom_nonce
}).then(function (res) {
    msg = res.json().msg;
});

This is all run in wp-admin. The issue is that the wp-admin page/JS script itself is loaded as a logged in user, but the AJAX request that ends up into admin-ajax.php is done as a logged out guest user. This leads to the issue of wp-admin using nopriv and check_ajax_referrer failing 100% of the time.

Why does wp-admin make AJAX requests as a guest instead of the logged in user?

Currently, the AJAX endpoint returns 403 status with -1 content, as it should in case there is a nonce mismatch. If I comment out the check_ajax_referrer() call then the AJAX request runs through successfully. After some furious console.logging I've determined that the nonce values match in the JS fetch call and the AJAX endpoint that receives it (which means the nonce is properly transferred, but a wrong guest nonce is generated during the AJAX endpoint execution.

If I remove the wp_ajax_nopriv_foobar_action then WordPress doesn't find the auth-enabled AJAX action because there seemingly is no logged in user available (results in status 200 and body 0).

Steps I've attempted to fix the issue:

  • Logged out and in again, used incognito windows,
  • Restarted PHP-FPM, Nginx, object cache backends, MariaDB,
  • Disabled all plugins that are not required for operation,
  • Moved the AJAX hooking code around in my plugin code, all the way to the plugin root file (e.g. myplugin/myplugin.php).