admin管理员组

文章数量:1435859

Okay, so I am a bit confused about something with Meteor.js. I created a site with it to test the various concepts, and it worked fine. Once I removed "insecure" and "autopublish", I get multiple "access denied" errors when trying to retrieve and push to the server. I belive it has something to do with the following snippet:

Template.posts.posts = function () {
    return Posts.find({}, {sort: {time: -1}});
}

I think that it is trying to access the collection directly, which it was allowed to do with "insecure" and "autopublish" enabled, but once they were disabled it was given access denied. Another piece I think is problematic:

else {
    Posts.insert({
    user: Meteor.user().profile.name,
    post: post.value,
    time: Date.now(),
});

I think that the same sort of thing is happening: it is trying to access the collection directly, which it is not allowed to do.

My question is, how do I re-factor it so that I do not need "insecure" and "autopublish" enabled?

Thanks.

EDIT

Final:

/** 
* Models
*/
Posts = new Meteor.Collection('posts');

posts = Posts

if (Meteor.isClient) {

    Meteor.subscribe('posts');


}

if (Meteor.isServer) {

    Meteor.publish('posts', function() {
        return posts.find({}, {time:-1, limit: 100});
   });


    posts.allow({

        insert: function (document) {
            return true;
        },
        update: function () {
            return false;
        },
        remove: function () {
            return false;
        }

    });

}

Okay, so I am a bit confused about something with Meteor.js. I created a site with it to test the various concepts, and it worked fine. Once I removed "insecure" and "autopublish", I get multiple "access denied" errors when trying to retrieve and push to the server. I belive it has something to do with the following snippet:

Template.posts.posts = function () {
    return Posts.find({}, {sort: {time: -1}});
}

I think that it is trying to access the collection directly, which it was allowed to do with "insecure" and "autopublish" enabled, but once they were disabled it was given access denied. Another piece I think is problematic:

else {
    Posts.insert({
    user: Meteor.user().profile.name,
    post: post.value,
    time: Date.now(),
});

I think that the same sort of thing is happening: it is trying to access the collection directly, which it is not allowed to do.

My question is, how do I re-factor it so that I do not need "insecure" and "autopublish" enabled?

Thanks.

EDIT

Final:

/** 
* Models
*/
Posts = new Meteor.Collection('posts');

posts = Posts

if (Meteor.isClient) {

    Meteor.subscribe('posts');


}

if (Meteor.isServer) {

    Meteor.publish('posts', function() {
        return posts.find({}, {time:-1, limit: 100});
   });


    posts.allow({

        insert: function (document) {
            return true;
        },
        update: function () {
            return false;
        },
        remove: function () {
            return false;
        }

    });

}
Share Improve this question edited Sep 23, 2013 at 10:45 Aristides asked Sep 22, 2013 at 18:22 AristidesAristides 3,9457 gold badges35 silver badges42 bronze badges 1
  • yes, you declare the variable 'Posts' but try to access it with 'posts' on the server. You should correct the typo as now you have a question and answer showing code which won't run. – user728291 Commented Sep 23, 2013 at 0:31
Add a ment  | 

1 Answer 1

Reset to default 7

Ok, so there are two parts to this question:

Autopublish

To publish databases in meteor, you need to have code on both the server-side, and client-side of the project. Assuming you have instantiated the collection (Posts = new Meteor.Collection('posts')), then you need

if (Meteor.isServer) {
    Meteor.publish('posts', function(subsargs) {
        //subsargs are args passed in the next section
        return posts.find()
        //or 
        return posts.find({}, {time:-1, limit: 5}) //etc
   })
}

Then for the client

if (Meteor.isClient) {
    Meteor.subscribe('posts', subsargs) //here is where you can pass arguments
}

Insecure

The purpose of insecure is to allow the client to indiscriminately add, modify, and remove any database entries it wants. However, most of the time you don't want that. Once you remove insecure, you need to set up rules on the server detailing who can do what. These two functions are db.allow and db.deny. E.g.

if (Meteor.isServer) {
    posts.allow({ 
        insert:function(userId, document) {
            if (userId === "ABCDEFGHIJKLMNOP") {  //e.g check if admin
                return true;
            }
            return false;
        },
        update: function(userId,doc,fieldNames,modifier) {
            if (fieldNames.length === 1 && fieldNames[0] === "post") { //they are only updating the post
                return true;
            }
            return false;
        },
        remove: function(userId, doc) {
            if (doc.user === userId) {  //if the creator is trying to remove it
                return true;
            }
            return false;
        }
    });
}

Likewise, db.deny will behave the exact same way, except a response of true will mean "do not allow this action"

Hope this answers all your questions

本文标签: javascriptMeteorjs Publishing and SubscribingStack Overflow