1

I have a voting system where a list of posts are printed out using an archive template. Each post's voting button has html data attributes containing the vote-id and the vote-nonce.

When the voting button is clicked an AJAX call is made containing the vote-id, and the vote-nonce. These should be verified server side but they appear to be failing wp-verify-nonce. Debugging and echoing the posted data confirms that it is identical to the original data.

AJAX PHP Function:

function submit_vote() {
    $vote_id = intval($_POST['vote_id']);
    $vote_nonce = sanitize_text_field($_POST['vote_nonce']);
    $action = sanitize_text_field($_POST['vote_nonce']);

    if ( !wp_verify_nonce($vote_nonce,'vote-nonce-' . $vote_id))
        die(-1);

    $response = json_encode( array( 'success' => true ) );
    die($response);
}
add_action( 'wp_ajax_submit_vote', 'submit_vote' );

NONCE Generation:

wp_create_nonce( 'vote-nonce-' . get_the_ID() );

AJAX JavaScript call:

jQuery(document).ready(function(){
  jQuery(".post-voting").click(function(){
    vote_nonce = jQuery(this).data('vote-nonce');
    vote_id = jQuery(this).data('vote-id');

    jQuery.post(
      vote_ajax.url,
      {
        action: 'submit_vote',
        vote_id: vote_id,
        vote_nonce: vote_nonce
      },
      function( data ) {
        alert( jQuery.parseJSON(data) );
      }
    );
  });
});

The ajax request appears to be just dying with an empty response (not -1)

  • The AJAX call will die with null data as per die(-1) which should be die('-1') for your voting system. Did you var_dump( $_REQUEST ) to make sure all data are there? – Samuel Elh Jun 26 '16 at 22:53
  • yep, i've tried the var_dump and all the data is there. – Stephen Mahood Jun 26 '16 at 22:59
  • Try this wp_create_nonce( 'vote-nonce' ) and then wp_verify_nonce($vote_nonce,'vote-nonce'), to see if it has to do with the identifier – Samuel Elh Jun 26 '16 at 23:01
  • tried that as well. Didn't seem to make a difference. I'm wondering if it's something to do with my cookie paths, my admin bar isn't showing up in the front end. Do you know if the cookies are needed for nonce validation? – Stephen Mahood Jun 26 '16 at 23:04
  • Yes. Nonces rely on wp_get_session_token() tokens which are based on cookies e.g LOGGED_IN_COOKIE – Samuel Elh Jun 26 '16 at 23:12
0

To verify nonces in Ajax requests, check_ajax_referrer() should be used instead of wp_verify_nonce():

Crete the nonce:

$nonce = wp_create_nonce( 'vote-nonce-' . get_the_ID() );

Include it in JavaScript:

jQuery(document).ready(function(){
  jQuery(".post-voting").click(function(){
    vote_nonce = <?php echo $nonce; ?>
    vote_id = jQuery(this).data('vote-id');

    jQuery.post(
      vote_ajax.url,
      {
        action: 'submit_vote',
        vote_id: vote_id,
        vote_nonce: vote_nonce
      },
      function( data ) {
        alert( jQuery.parseJSON(data) );
      }
    );
  });
});

Check in the ajax callback:

add_action( 'wp_ajax_submit_vote', 'submit_vote' );
function submit_vote() {

    $vote_id = intval( $_POST['vote_id'] );
    $vote_nonce_name = 'vote-nonce-' . $vote_id;

    // By default, check_ajax_referer dies if nonce can not been verified
    if( ! check_ajax_referer( $vote_nonce_name, 'vote_nonce', false ) ) {
        wp_send_json_error();
    } else {
        wp_send_json_success();
    }

}
  • using the check_ajax_referer and the cookie issue I mentioned above seems to have resolved my issue – Stephen Mahood Jun 27 '16 at 22:19

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.