Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting values from the server

Tags:

meteor

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!

like image 554
Samo Avatar asked Apr 22 '12 04:04

Samo


People also ask

Which method should you use to read data from the server?

Simply put, the GET method is used to retreive data from a server at the specified resource.

How will you fetch data from server in JS?

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.


2 Answers

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.)

like image 88
debergalis Avatar answered Oct 14 '22 16:10

debergalis


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.

like image 38
Dan Dascalescu Avatar answered Oct 14 '22 15:10

Dan Dascalescu