2

I'm trying to create and verify nonce, and I did it almost the same way as described in wp_create_nonce.

I believe it's related to REST api, but not sure where to investigate?

How I create nonce:

(I have an REST function that returns codes to draw up HTML, which properly draws up the HTML, where the resulting value of wp_create_nonce() filled up properly)

/***
 * Display customers/vendors in table format
 ***/

if( !function_exists( 'fnc_view_customer_vendor_in_table_format' ) ) {
    /**
     * @param WP_REST_Request $request
     * @return mixed|string|void
     */
    function fnc_view_customer_vendor_in_table_format(WP_REST_Request $request ) {

        $_search_name = $request['_search_name'];
        $_posttype = $request['_posttype'];

        if( $_posttype == null ) {
            $result = array( 'msg' => 'ERROR: Please try again', 'error' => true );
            return json_encode( $result );
        }

        $data = '<table class="table widefat table-striped">';
        $data .= '<thead>';
        $data .= '<tr>';
        $data .= '<th class="col-name">Name</th>';
        $data .= '<th class="col-phone">Phone</th>';
        $data .= '<th class="col-email">Fax</th>';
        $data .= '<th class="col-email">Email</th>';
        $data .= '<th class="col-website">Website</th>';
        $data .= '<th class="col-action">Actions</th>';
        $data .= '</tr>';
        $data .= '</thead>';
        $data .= '<tbody>';

        $args = array(
            'post_type' => $_posttype,
            'post_status' => 'publish',
            'posts_per_page' => -1
        );

        if( $_search_name ) {
            $search_args = array(
                's' => $_search_name
            );
            $args = wp_parse_args( $args, $search_args );
        }

        $posts = get_posts( $args );

        $del_page = get_permalink( fnc_get_id_by_slug_and_posttype( 'delete-instance', 'page' ) );

        foreach( $posts as $post ) :

            $post_type = get_post_type( $post->ID );

            $data .= '<tr>';

            $data .= '<th class="col-name">';
            $data .= get_the_title( $post->ID );
            $data .= '</th>';

            $data .='<th class="col-phone">';
            $data .= get_post_meta( $post->ID, '_phone', true );
            $data .= '</th>';

            $data .= '<th class="col-fax">';
            $data .= get_post_meta( $post->ID, '_fax', true );
            $data .= '</th>';

            $data .= '<th class="col-email">';
            $data .= get_post_meta( $post->ID, '_email', true );
            $data .= '</th>';

            $data .= '<th class="col-website">';
            $data .= '<a href="'.get_post_meta( $post->ID, '_website', true ).'" target = "_new">';
            $data .= get_post_meta( $post->ID, '_website', true );
            $data .= '</a>';
            $data .= '</th>';

            $data .='<th class="col-action">';
            $data .='<div class="col-action-btn">';
            $data .='<div class="col-action-edit">';
            $data .='<form action="' . get_permalink( $post->ID ) . '" id="form-edit" name="form-edit" method="post">';
            $data .='<!-- Noncename needed to verify where the data originated -->';
            $data .= '<input type="hidden" id="_wpnonce" name="_wpnonce" value="'. wp_create_nonce( 'edit_post-'. $post->ID ) .'" />';
            $data .= '<input type="hidden" name="_wp_http_referer" value="/test/lists/view-vendors" />';
            $data .= '<input type="hidden" id="post_id" name="post_id" value="'. $post->ID .'" />';
            $data .='<input type="hidden" name="mode" value="edit">';
            $data .='<input type="submit" class="btn btn-small" value="Edit">';
            $data .='</form>';
            $data .='</div>';
            /*
            $data .='<div class="col-action-delete">';
            $data .= '<form action="' . $del_page . '" id="form-delete" name="form-delete" method="post"  />';
            $data .= '<!-- Noncename needed to verify where the data originated -->';
            $data .= '<input type="hidden" id="_wpnonce" name="_wpnonce" value="'. wp_create_nonce() .'" />';
            $data .='<input type="hidden" name="mode" value="delete" />';
            $data .='<input type="hidden" name="del_post_id" value=" ' .$post->ID . '" />';
            $data .='<input type="hidden" name="del_post_type" value=" ' .$post_type . '" />';
            $data .='<input type="submit" class="btn btn-small" value="Delete" />';
            $data .='</form>';
            */
            $data .= '</th>';

            $data .= '</tr>';

        endforeach;

        $data .= '</tbody>';
        $data .= '</table>';

        $result = array( 'msg' => $data, 'error' => false );

        return json_encode( $result );

    }
}

How I validate nonce:

  // Nonce from other pages
  $nonce = $_REQUEST['_wpnonce'];
  $post_id = $_REQUEST['post_id'];

  print_r( $_POST );
  // prints Array ( [_wpnonce] => 47f80a1859 [_wp_http_referer] => /test/lists/view-vendors [post_id] => 19793 [mode] => edit )
  echo '<br/>';
  echo '<br/>';

  var_dump( wp_verify_nonce( $nonce, 'edit_post-'. $post_id ) );
  // prints bool(false)
  echo '<br/>';
  echo '<br/>';

    if ( !wp_verify_nonce( $nonce, 'edit_post-'. $post_id ) ) {

        print $GLOBALS['doumi']['nonce_fail_msg'];
        echo '</main></div>';
        get_footer();
        die();

    }
  • if it return a value it should not, it is very probable that you don't call it. set a "breakpoint" in the function to make sure you get there. most likely it is being overriden by some plugin – Mark Kaplun Apr 9 '17 at 17:57
  • I did not install any plugin and I am pretty sure that my function is get called since the $_POST variables echo proper values right before wp_verify_nonce. – Dongsan Apr 9 '17 at 23:28
  • it is software engineering, not voodoo. If a function has a return 4 and you get 1, it means that you called something else instead. – Mark Kaplun Apr 10 '17 at 2:37
  • This post websupporter.net/blog/de/nonces-in-der-rest-api is in German language, but really helpful, and maybe readable for you with a translating service. – bueltge Apr 10 '17 at 7:56
  • 1
    @bueltge Thanks for the advice, but the thing is that I am preparing the code for echoing the nounce in REST, which is actually echoed in normal Wordpress page. So it' a bit different situation from the article you suggested. – Dongsan Apr 10 '17 at 13:15
1

In line 3 of your form markup, you're passing two arguments to wp_create_nonce when it only accepts one. It's a simple typo. You'll want to concatenate the string like so:

wp_create_nonce( 'edit_post-'. $post->ID ) //dot instead of comma

EDIT: I'd suggest you give the nonce field a more specific name than _wpnonce, as this is the generic(default) Wordpress name for nonce fields, which means you probably have a conflict with other core nonces or a plugin nonce. Maybe try something like this:

// change the NONCE name to something unique
$data .= '<input type="hidden" id="wpse263026_nonce" name="wpse263026_nonce" value="'. wp_create_nonce( 'edit_post-'. $post->ID ) .'" />';
  • Corrected the typo from comma to dot, but it still yields EMPTY. The value of wp_create_nonce() in the function is the same as the value of $_REQUEST['_wpnonce'] in the validator, and the value of $post->ID in the function is the same as the value of $_REQUEST['post_id']. BUt still it isn't working. – Dongsan Apr 9 '17 at 16:42
  • Can you do var_dump($result); instead of echo and post the results? – Spartacus Apr 9 '17 at 18:45
  • Well, I thought $result is empty or null since print_r( $result ) didn't yield anything. Now it yields bool(false) with var_dump( $result ). I didn't know print_r and var_dump give different results. Anyways, I'm not sure why it yields bool(false)... – Dongsan Apr 9 '17 at 23:36
  • An empty string equates to false in PHP, and this is what I suspected. I will edit my answer to further help you – Spartacus Apr 10 '17 at 2:56
  • @Spartacua I tried many times with wp_nonce_field (), but it is not appended to $data. That is, the return value (input code) of wp_nonce_field () is not added to a variable and my code is just interrupted there. – Dongsan Apr 11 '17 at 5:04

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.