Access checks with custom REST endpoints and backbone

I have created a plugin in with several custom REST endpoints. However I can not get the permission callbacks to work. Current user is always '0'. I'm using localize script to send the nonce.

        wp_localize_script( $this-cloud_base, 'POST_SUBMITTER', array(
        'root' = esc_url_raw( rest_url() ),
        'nonce' = wp_create_nonce( 'wp_rest' ),
        'success' = __( 'Data Has been updated!', 'your-text-domain' ),
        'failure' = __( 'Your submission could not be processed.', 'your-text-domain' ),
        'current_user_id' = get_current_user_id()
        )
    ); 

And then in the javascript code i'm modifying the sync function to return the nonce:

    app.Model = Backbone.Model.extend({
// over ride the sync function to include the Wordpress nonce.  
    sync: function( method, model, options ){
        return Backbone.sync(method, this, jQuery.extend( options, {
            beforeSend: function (xhr) {
            alert(POST_SUBMITTER.nonce);  // nonce is shown here. 
            xhr.setRequestHeader( 'X-WP-NONCE', POST_SUBMITTER.nonce );
            },
        } ));   
    },  
});

Backbone is used to general a list of items from the REST endpoint and generate a form for adding or updating. (everything works fine if I disable access checks.)

In my access check the current user is always 0

    public function cloud_base_members_access_check(){  
    if (  current_user_can( 'read' )) {
        return true;
    }
    return new \WP_Error( 'rest_forbidden', esc_html__( 'Sorry, you are not authorized for that.', 'my-text-domain' ), array( 'status' = 401 ) );
}   

The Wordpress REST handbook seams to suggest this should just work. I've combined element from several different examples trying to make this work, but I have found no example of how to make this all work together. Have been trying to make this work for about a week now and I am out of ideas? Any suggestion as to how to make this work?

Topic backbone rest-api Wordpress javascript

Category Web


The issue was I overrode the Backbone.sync method only in Backbone.Model. When Backbone fetches the initial data (GET) it is using the sync method in Backbone.collections. So I need to override the sync in Backbone.Collections:

app.Collection = Backbone.Collection.extend({   
    sync: function( method, model, options ){
        return Backbone.sync(method, this, jQuery.extend( options, {
            beforeSend: function (xhr) {
            xhr.setRequestHeader( 'X-WP-NONCE', POST_SUBMITTER.nonce );
            },
        } ));   
    },  
 }) ; 

With that the nonce is sent with the GET request as well as POST, PUT and DELETE.

You might be able to override Backbone.sync and thus cover both Model and Collection at once.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.