Let's say I don't want my client to have access to a collection, but I do want my client to be able to ask certain questions about objects within that collection. How would I achieve this?
As an example, let's say I want to know if there's currently a user logged in. When a user first logs in, I set that user's database id in Session
and in a cookie. Currently, the application says a user is logged in if !Session.equals("user_id", null)
, which of course is very insecure because now I can open firebug and say Session.set("user_id", "foo")
and now I'm logged in.
I don't want the client to have access to the Users collection at this point. The only client code that has access to this collection is enclosed in a self executing function in an effort to protect it (I'm not really sure if that's the right way to do security in Meteor, so feel free to recommend something along those lines as well). So instead I'd like to call some server side code and pass it the id that's set in session and have it tell me if that's a valid user or not.
Here's how I'd like to see it setup:
// client
function logged_in() {
return SomeServerMethodThatValidatesUserId(Session.get("user_id"));
}
Meteor.methods
doesn't seem to fit the bill, since Meteor.call
performs an asynchronous callback. The pub/sub model looks a little more promising, but from the documentation, I'm not quite sure how it works.
It seems to suggest that I should call this.set
from within the publish handler in order to set some values on the client, but I can't figure out where those values become available.
Or maybe the pub/sub model isn't right for this either and there's another way that I'm missing. Any advice is appreciated!
Simply put, the GET method is used to retreive data from a server at the specified resource.
The simplest use of fetch() takes one argument — the path to the resource you want to fetch — and returns a promise containing the response (in the form of a JavaScript object). To extract the JSON body content from the response, we use the JSON. stringify(myJson) method.
It sounds like you're trying to restrict the client from accessing data until it's been authenticated. Here's one way to do that:
First, write a Meteor.publish
function on the server that takes a user_id
argument. Your function does whatever check you want in the privileged server environment and ultimately returns a Cursor. One simple example would be:
// define collection on both client and server
Users = new Meteor.Collection('users');
// server-side publish
Meteor.publish('my-user', function (user_id) {
if (someServerMethodThatValidatesUserId(user_id))
// publish a single user object to the client
return Users.find({_id: user_id});
});
Then on the client, subscribe to the my-user
set once you have a user_id
in hand:
// client-side
Meteor.subscribe('my-user', Session.get('user_id'));
Now, you'll have one document in Users on the client if and only if the user_id
was valid, as determined by your privileged function someServerMethodThatValidatesUserId
that runs on the server.
(this.set
is available inside your publish function if you want to manually manage the specific documents that get sent to the client, instead of relying on a Mongo query. But I don't think anything like that is necessary here.)
This is an old question from the age before Meteor had authentication. The TL;DR answer is:
meteor remove autopublish
Then, manage your own collections, publications and subscriptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With