Search code examples
meteoriron-router

Meteor.userId can only be invoked in method calls. (Meteor IronRouter)


I'm using IronRouter for my app. Recently I wanted to do a rest call:

Router.route('/api/hello', { where: 'server' })
  .get(function () {
    this.response.end('Helo world');
});

And I got this exception:

Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. at AccountsServer.userId (accounts_server.js:80:13) at AccountsServer.user (accounts_common.js:53:23) at Object.Meteor.user (accounts_common.js:230:19) at [object Object]. (lib/routes_permission.js:33:21) at packages/iron_router/lib/router.js:277:1 at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1) at [object Object].hookWithOptions (packages/iron_router/lib/router.js:276:1) at boundNext (packages/iron_middleware-stack/lib/middleware_stack.js:251:1) at runWithEnvironment (packages/meteor/dynamics_nodejs.js:110:1) at packages/meteor/dynamics_nodejs.js:123:1

I tracked the issue in '(lib/routes_permission.js:33:21)' And seems everything is fine.

// user with no role
Router.onBeforeAction(function() {
  var user = Meteor.user(); //This is the line.
  if(user && !user.roles) {
    this.render('roles');
    return;
  }
  this.next();
});

I don't know why I'm getting this exception. I don't have any Meteor.userId() in my publications though.

Any insights ?


Solution

  • Server-side routes are accessed like REST endpoints, so they don't have the notion of authentication (Meteor.user and Meteor.userId will throw an error). Because your routes_permission.js file is defined in a shared directory, its rules are getting picked up for the server routes as well. You have some choices about how to fix this, but the easiest may be just to wrap your onBeforeAction with Meteor.isClient like so:

    if (Meteor.isClient) {
      Router.onBeforeAction(...);
    }