使用服务器路由和onBeforeAction时出现异常

时间:2014-12-29 17:22:34

标签: javascript node.js meteor iron-router

我在尝试添加pdf文件时看到了奇怪的行为。

if语句中的以下代码抛出: 既\ routes.js

Router.onBeforeAction(function () {   if (!Meteor.user() || Meteor.loggingIn()) {
    this.redirect('welcome.view');   }   else {
    Meteor.call("userFileDirectory", function (error, result) {
      if (error)
        throw error;
      else
        console.log(result);
 });
    this.next();   } }, {   except: ['welcome.view'] });
  

错误:Meteor.userId只能在方法调用中调用。使用   发布函数中的this.userId。在Object.Meteor.userId   (packages / accounts-base / accounts_server.js:19:1)在Object.Meteor.user上   (packages / accounts-base / accounts_server.js:24:1)在[object   对象] .Router.onBeforeAction.except   (app / both / 3-router / routes.js:10:15)at   packages / iron:router / lib / router.js:277:1 at [object   对象] ._。extend.withValue(packages / meteor / dynamics_nodejs.js:56:1)   at [object Object] .hookWithOptions   (packages / iron:router / lib / router.js:276:1)在boundNext   (packages / iron:middleware-stack / lib / middleware_stack.js:251:1)at   runWithEnvironment(packages / meteor / dynamics_nodejs.js:108:1)at   packages / meteor / dynamics_nodejs.js:121:1在[object Object] .dispatch   (包/铁:中间件栈/ LIB / middleware_stack.js:275:1)

只有当我将此代码添加到文件中时,才会执行/ pdf路由:

Router.route('/pdf', function() {
  var filePath = process.env.PWD + "/server/.files/users/test.pdf";
  console.log(filePath);
  var fs = Npm.require('fs');
  var data = fs.readFileSync(filePath);
  this.response.write(data);
  this.response.end();
}, {
  where: 'server'
});

以上代码工作正常;当我取出onBeforeAction代码时,pdf呈现在屏幕上并且不会抛出任何异常。

反之亦然,如果我取出服务器路由,则没有导致异常的路由。

2 个答案:

答案 0 :(得分:1)

这是因为您使用的路由是服务器端路由。 Meteor用于验证用户的技术是通过DDP协议通过websockets完成的。

当您的浏览器向服务器发出GET / POST请求时,它没有任何有关用户身份验证状态的信息。

您在Meteor.user()中使用Route.onBeforeAction,但无法访问此信息。

解决方法是找到另一种验证用户身份的方法。一种这样的方法是使用cookie。

这是Meteor身份验证系统的已知问题,请参阅:https://github.com/EventedMind/iron-router/issues/649

答案 1 :(得分:1)

比cookie更好的方法可能是存储userId和一些sessionId的Meteor的命名集合:

您可以在调用服务器之前在客户端存储当前的userId:

var sessionId = Random.id(); 
col = new Mongo.Collection('session');
col.insert({
  sessionId: sid,
  userId: Meteor.userId(),
  issued: new Date()
});

然后通过sessionId请求将GET/POST传递给服务器并在服务器上读取它:

var sid = this.request.query.sid;
var user = col.findOne({sessionId: sid}); // returns an object

使用单独的参数比使用userId本身更好,因为您可以在一段时间后或服务器调用后立即撤销此sessionId

需要正确的allow/deny权限才能阻止任何人更新集合。另请注意,您不能信任客户方new Date()