1

I've written a class to play about with ajax. I had originally used check_admin_referer (in hello()) without arguments but got this warning: "PHP Notice: check_admin_referer was called incorrectly. You should specify a nonce action to be verified by using the first parameter."

So I headed to the codex and have tried to follow the example. However, the check fails. I'm now getting a 403.

Here is my class:

class StupidClass {

    private $settings_page;

    // scripts, 
    public function __construct(){
        add_action('admin_menu', array($this, 'add_menu'));
        add_action('admin_enqueue_scripts', array($this, 'load_scripts'));
        add_action('wp_ajax_hello', array($this, 'hello'));
    }

    // setup
    public function add_menu(){
        $this->settings_page = add_menu_page( 'Menu item', 'settings page', 'edit_pages', 'settingspage', array($this, 'render_page'), false, 62 );
    }

    public function load_scripts($hook){
        if ($this->settings_page !== $hook) {
            return;
        }

        $path = plugin_dir_url( __FILE__ ) . 'stupid.js';
        wp_enqueue_script( 'stupid_js', $path, array('jquery'));
    }

    // view
    public function render_page(){
        ?>
        <h1>This is the title</h1>
        <form action="" id="stupid_form" method="post">
            <?php wp_nonce_field('hello', 'token'); ?>
            <input type="submit" value="hit me">
        </form>
        <div id="response"></div>
        <?php
    }

    public function hello(){
        check_admin_referer('hello', 'token');
        wp_die();
    }
}

The only reason I can think of is that the action name is incorrect because I am not pointing to the instance method but I'm new to PHP and WP, and my Google foo is failing me.

What am I doing wrong. How do I get check_admin_referer() to pass?

Update

Here is the JS:

jQuery(document).ready(function($){
    data = {
        action: 'hello'
    }
    $('#stupid_form').submit(function(){
        $.post(ajaxurl, data, function(response){
            $('#response').html(response);
        });
        return false;
    });
});
3

In the JS script, include the nonce in data, as in the following example:

jQuery(document).ready(function($){
    data = {
        action: 'hello',
        token: $( '#token' ).val()
    }
    $('#stupid_form').submit(function(){
        $.post(ajaxurl, data, function(response){
            $('#response').html(response);
        });
        return false;
    });
});

Additional Note

<?php wp_nonce_field('hello', 'token'); ?>

generates a hidden input with a markup similar to:

<input type="hidden" id="token" name="token" value="d9e3867a0e" />

i.e. the nonce name becomes the name as well as id of the input.

That explains the token: $( '#token' ).val() in the code I provided, where the format is NONCE_NAME: $( '#NONCE_NAME' ).val().

However, you may also target the name like so: token: $( 'input[name="token"]' ).val()

1

As the name implies check_admin_referer checks that the referer was an admin page. Wordpress usually will add a referer field as an hidden input to the admin forms, and you can do the same, but basically it should just not be used in AJAX unless your ajax is limited to admin side. Just use nonce verification instead.

In any case die-ing (which is what check_admin_referer does) is not the best strategy when handling AJAX requests and you most likely will want to have some more customized "error" indication and message.

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.