Not getting wordpress nonce to work with wp-rest api application

12,558

According to the docs:

For developers making manual Ajax requests, the nonce will need to be passed with each request. The API uses nonces with the action set to wp_rest. These can then be passed to the API via the _wpnonce data parameter (either POST data or in the query for GET requests), or via the X-WP-Nonce header.

The important part you are missing is:

The API uses nonces with the action set to wp_rest.

For it to work, you must name your action in the wp_create_nonce to wp_rest.

So for your code, you must change all instances of:

wp_create_nonce( "a" )

to

wp_create_nonce( 'wp_rest' )

Also, as the docs state:

Supplying the nonce as a header is the most reliable approach.

So adding this to your ajax is simple and looks something like:

var _nonce = "<?php echo wp_create_nonce( 'wp_rest' ); ?>";
$.ajax({
    type: 'POST',
    url: url_path + '/foo/v1/newbee',
    data: {
        bid : next
    },
    dataType: 'json',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', _nonce );
    }
});

Also, to fix the check

check_ajax_referer( 'a', $nonce, false )

Should now be

check_ajax_referer( 'wp_rest', '_nonce', false )
Share:
12,558

Related videos on Youtube

Ronnie Zweers
Author by

Ronnie Zweers

Updated on June 04, 2022

Comments

  • Ronnie Zweers
    Ronnie Zweers almost 2 years

    I have an app which is should be secure and therefore using Nonce's but I can't get them to work. I have tried several options but apparently something is missing as the validation doesn't work.

    My js code fragment is:

    function placeNew(next){
      _nonce = $('input#_nonce').val();
      request = $.ajax({
        type: 'POST',
        url: url_path + '/foo/v1/newbee',
        data: {bid : next , _nonce : _nonce},
        security: '<?php echo wp_create_nonce( "a" ); ?>',
        dataType: 'json'
    });
    request.done(function (response, textStatus, jqXHR){
      str = JSON.stringify(response);
      if(response["error"]){
        alert(response["message"]);
      }
    

    The nonce is added to the page with the following code:

    $nonce = wp_create_nonce( 'a' );
    echo "<input type='hidden' id='_nonce' value=" . $nonce ."/>";
    

    Within php the following function fragment is used to get and compare the nonce:

    function ace($request) {
        global $wpdb;
        $timestamp = time();
        $nonce = (string) $request['_nonce'];
        $verify = check_ajax_referer( 'a', $nonce, false );
        if ( ! $verify){
            $errMsg = $nonce . '-'. $verify .' not validated ';
            return (object) array(error => true, message => $errMsg);
        }
    

    I always do get the message "not validated". $nonce has a value but $verify never gets a value.