最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Access checks with custom REST endpoints and backbone

programmeradmin3浏览0评论

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?

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?

Share Improve this question asked Oct 1, 2020 at 14:05 dsjdsj 638 bronze badges 4
  • Have you inspected the network requests (XHR) to check if the nonce header did get sent? And are you aware of the wp-api script and that you can extend its models and collections (e.g. for custom post types)? – Sally CJ Commented Oct 1, 2020 at 17:00
  • I tried checking the nonce with "check_ajax_referer() and by looking at $_REQUEST['wp_rest'} and no it does not appear to be set. Not clear how 'wp-api' would help I have it enqued and it should help with the part where I need to access USER info, but I don't see how that help with my custom endpoints. It appears to be concerned with the standard WP stuff, users, post, comments etc.. – dsj Commented Oct 1, 2020 at 17:16
  • 1 I'm actually referring to tools like the Network tab in Chrome Developer Tools.. details here. Try it out. – Sally CJ Commented Oct 1, 2020 at 17:32
  • I'm using Safari, but have similar set of tools. I went back and rechecked, and realized I was confusing error messages. It is actually sending the nonce on POSTS but not GETs. Important clue...thanks for the suggestion. (so my POSTS work) – dsj Commented Oct 1, 2020 at 18:44
Add a comment  | 

1 Answer 1

Reset to default 0

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.

发布评论

评论列表(0)

  1. 暂无评论