Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Meteor.user() to return on the server side?

Tags:

meteor

in a file called /server/main.js (in order to ensure it is loaded last).

console.dir(Meteor.user()); 

Throws:

Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. 

So I try to use, in the same file:

console.dir(this.userId); 

returns:

undefined 

so, not giving up, I'm thinking "that's fine I'll just read from the cookies in the header":

var connect = Npm.require('connect');  __meteor_bootstrap__.app.use(connect.query()).use(function(req, res, next) {     console.dir(req.headers);     next(); }); 

.... returns nothing in terms of cookies except for 'cookie: 'uvf=1''

I'm not sure what to conclude - this is senseless as I can otherwise use the Meteor.Account framework just fine, read/set user properties, etc. The server is clearly aware of the user, and the current user clearly logged in.

I'm at a complete loss, any explanation / hint / pointer would be greatly appreciated.

like image 445
Stephan Tual Avatar asked May 13 '13 22:05

Stephan Tual


2 Answers

You have to use Meteor.user() in a place where a request is made from the client (such as a Meteor.methods or a Meteor.publish).

It can't be placed anywhere else because meteor wouldn't know at that point in the code the user is supposed to bound to. If there is a place a request of some form is made from the client it can do this:

In a Meteor.publish:

Meteor.publish("collection", function() {     //returns undefined if not logged in so check if logged in first     if(this.userId) {         var user = Meteor.users.findOne(this.userId);         //var user is the same info as would be given in Meteor.user();     } }); 

In a Meteor.methods:

Meteor.methods({     "test":function() {         //should print the user details if logged in, undefined otherwise.         console.log(Meteor.user());     } } 

To use Meteor.user() on a server side route:

You need Meteor router installed as a package via meteorite to allow you to have a server rendered page. (installed via mrt install router)

A server side route could then handle the web request:

 Meteor.Router.add('/awebpage', function(id) {      var userId = this.params.userid;      var logintoken = this.params.logintoken;      var isdirect = this.param.direct;      var user = Meteor.users.findOne({_id:userId,"services.resume.loginTokens.token":logintoken});      if(user) {          //the user is successfully logged in           return "You, "+user.profile.name+", are logged in!";      }      else      {          if(isdirect) {              return "<h3>Loading</h3><script>window.location.href="/awebpage?direct=true&userid="+localStorage.getItem("Meteor.userId") +"&logintoken="+localStorage.getItem("Meteor.loginToken")</script>";          }          else          {              return "Not logged in"          }      }  }); 

So now when you visit /awebpage it would check whether the user is logged in and do the thing you want when they are logged in. Initially there is a redirect to relay the data from localstorage back to the URI.

like image 134
Tarang Avatar answered Sep 18 '22 08:09

Tarang


You can expose the userId with Meteor.publish() to global scope. Then you can use it with Meteor.Router's server side routes.

--

/server/publications.js

CurrentUserId = null; Meteor.publish(null, function() {     CurrentUserId = this.userId; }); 

-

/server/routes.js

Meteor.Router.add('/upload', 'POST', function() {     if (!CurrentUserId)         return [403, 'Forbidden'];      // proceed with upload... }); 
like image 20
user2139950 Avatar answered Sep 19 '22 08:09

user2139950