Ajax in WordPress not working for logged in users without wp_ajax_nopriv action


I had a rather interesting problem the other day. My ajax request was not working if I didn’t use the wp_ajax_nopriv_ action on a page where the user was clearly logged in. Why? Why was this happening?

Here was the situation:

  • forced ssl on wp-admin so the localised url I was using for Ajax was eg https://example.com/wp-admin/admin-ajax.php
  • page requesting ajax was not ssl eg http://example.com/page-with-ajax
  • using wp_ajax_$action only, not wp_ajax_nopriv_$action as it was only for logged in users

Even with everything seemingly set up correctly, it was returning 0. WHY? Turns out that Ajax strips cookies and http authentication data on cross domain requests. And going from http://example.com to https://example.com is cross domain. If I can’t send the WordPress user’s cookies, I can’t use the wp_ajax_$action. See here from wp-admin/admin-ajax.php:77

[code lang=php]
if ( is_user_logged_in() ) {
/**
* Fires authenticated AJAX actions for logged-in users.
*
* The dynamic portion of the hook name, `$_REQUEST['action']`,
* refers to the name of the AJAX action callback being fired.
*
* @since 2.1.0
*/
do_action( 'wp_ajax_' . $_REQUEST['action'] );
} else {
/**
* Fires non-authenticated AJAX actions for logged-out users.
*
* The dynamic portion of the hook name, `$_REQUEST['action']`,
* refers to the name of the AJAX action callback being fired.
*
* @since 2.8.0
*/
do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
}
[/code]

So what’s the way around it? I decided to force my requesting page to https as it probably should have been already. You could also send the xhr withCredentials thing in your jQuery but don’t you need to add headers to the response? HEADERS, will someone please think of the headers? God people, really.

http://stackoverflow.com/questions/9559947/cross-origin-authorization-header-with-jquery-ajax

A quick explanation of it all: https://quickleft.com/blog/cookies-with-my-cors/

There is some sort of jsonp workaround that people refer to but I don’t know, I think the answer is probably to re-do admin-ajax.php as a plugin or something with all the proper things and then use that. Maybe not, it looks like everything is going to https anyway so might not matter soon at any rate.

Leave a Reply

Your email address will not be published. Required fields are marked *

By submitting this comment, you are agreeing to the use of Akismet which helps reduce spam. You can view Akismet’s privacy policy here. Your email, website and name are also stored on this site.