wp_verify_nonce always returns false when logged in as admin

I’ve implemented some AJAX functionality for my plugin and it works fine as long as I’m not logged in as admin – then wp_verify_nonce fails. It works for unauthorized users and authorized regular users too.

Here’s my PHP class (I removed everything that is not relevant to the issue):

class My_Ajax {
    function __construct() {
        add_action( 'wp_ajax_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_ajax_nopriv_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_enqueue_scripts', array($this, 'geoip_localize_js'), 11 );
    }

    function geoip_citylist() {
        if ( ! wp_verify_nonce($_POST['geoipNonce'], 'my_geoip_nonce') ) {
            exit('Wrong nonce: ' . $_POST['geoipNonce']);
        }
    }


    function geoip_localize_js() {
        wp_localize_script(
            'my_custom_js', 'myGeoipAjaxObject', 
            array( 
                'myGeoipNonce' => wp_create_nonce('my_geoip_nonce')
            ) 
        );
    }
}

And here’s my Javascript:

$.ajax({
    url: myMainAjaxObject.ajaxUrl,
    type: 'POST',
    dataType: 'json',
    data: {
        geoipNonce: myGeoipAjaxObject.myGeoipNonce,
        action: "geoip_citylist"
    },
    success: function(data) {
        replacePhones(data.user_city, data.current_phone, data.city_list);
    },
    error: function(error) {
        console.log(error);
    }
});

The nonce in PHP error response seems to be correct, but it still doesn’t validate for some reason.

I’ve spent days trying to figure out what’s wrong and trying to google this in every possible way, but so far I couldn’t find a solution that would work. There are unanswered questions with similar issues on stackoverflow, like this one which was created in 2011… I could just assume that nonces don’t work with admin accounts in WordPress, but I would like to at least get a confirmation before giving up.

UPDATE:
I’ve tried to use just the code that I provided here and it still resulted with the same error (I also double checked the cache and it was refreshed).

UPDATE 2:
myMainAjaxObject and its ajaxUrl are inserted in another script. Since AJAX URL is same for every AJAX request, I just use the global one instead of redefining it every time. So this is not what’s causing the error. Also if it wouldn’t be defined it would never work. Once again, it doesn’t work only for the admin, for other users and unauthorized users it works fine. And I do get “Wrong nonce: 73dd02f662” in the server response when I’m logged as admin. So I’m 100% sure that URL is correct.

2 Answers
2

I think the problem was that I manually deleted my cookies a few times while testing. Among them was a cookie called “wordpress_logged_in_{token}” where {token} is an unique identifier. My best guess is that lack of this cookie caused issues with nonce creation or/and verification. It was hard to notice because I was still able to browse the admin panel (it looks like there WP is using a different cookie called “wordpress_{token}”) and on the front end this website doesn’t show user status anywhere (accounts are not used there, however login functionality is there, just hidden from the view).

The solution was very simple – I just re-logged as admin and my AJAX started working for the admin as well. So if someone runs into a similar issue, make sure that when you clear cookies, you either delete only ones that you need to remove/regenerate or, if you delete all of them like I did, make sure to re-log as admin.

PS: I’m sorry I didn’t provide all the details from the start, but I did try to provide as much information as necessary. I knew I was missing something and now I feel stupid for even asking this question. However, I’m not going to delete it so that maybe someone who runs into the same issue could save some time.

Leave a Comment