Получение значений с сервера

Скажем, я не хочу, чтобы у моего клиента был доступ к коллекции, но я хочу, чтобы мой клиент мог задать некоторые вопросы об объектах в этой коллекции. Как я могу это достичь?

В качестве примера, скажем, я хочу знать, есть ли в настоящий момент пользователь, вошедший в систему. Когда пользователь впервые входит в систему, я устанавливаю идентификатор базы данных пользователя в Session и в файле cookie. В настоящее время приложение заявляет, что пользователь вошел в систему, если !Session.equals("user_id", null), что, конечно, очень небезопасно, потому что теперь я могу открыть firebug и сказать Session.set("user_id", "foo"), и теперь я вошел в систему.

Я не хочу, чтобы на данный момент у клиента был доступ к коллекции Пользователи. Единственный клиентский код, который имеет доступ к этой коллекции, прилагается к функции самоисполнения, чтобы защитить ее (я не совсем уверен, что это правильный способ сделать безопасность в Meteor, поэтому не стесняйтесь рекомендовать что-то по этим линиям также). Поэтому вместо этого я бы назвал код на стороне сервера и передал ему идентификатор, который был установлен в сеансе, и сообщите мне, является ли это действительным пользователем или нет.

Вот как я хотел бы увидеть его настройку:

// client
function logged_in() {
  return SomeServerMethodThatValidatesUserId(Session.get("user_id"));
}

Meteor.methods, похоже, не соответствует счету, так как Meteor.call выполняет асинхронный обратный вызов. Паб/под-модель выглядит несколько более перспективной, но из документации я не совсем уверен, как она работает.

Кажется, что я должен вызвать this.set из обработчика публикации, чтобы установить некоторые значения на клиенте, но я не могу понять, где эти значения становятся доступными.

Или, может быть, модель pub/sub не подходит для этого, и есть другой способ, который мне не хватает. Любые советы приветствуются!

Ответ 2

Похоже, вы пытаетесь ограничить доступ клиента к данным до его аутентификации. Вот один из способов сделать это:

Сначала напишите функцию Meteor.publish на сервере, которая принимает аргумент user_id. Ваша функция выполняет все необходимые проверки в привилегированной серверной среде и в конечном итоге возвращает курсор. Один простой пример:

// 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});
});

Затем на клиенте подпишитесь на my-user, если у вас есть user_id:

// client-side
Meteor.subscribe('my-user', Session.get('user_id'));

Теперь у вас будет один документ в "Пользователи на клиенте", если и только если user_id был действительным, как определено вашей привилегированной функцией someServerMethodThatValidatesUserId, которая выполняется на сервере.

(this.set доступен внутри вашей функции публикации, если вы хотите вручную управлять конкретными документами, которые отправляются клиенту, вместо того, чтобы полагаться на запрос Mongo. Но я не думаю, что здесь что-то нужно. )