我在尝试添加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呈现在屏幕上并且不会抛出任何异常。
反之亦然,如果我取出服务器路由,则没有导致异常的路由。
答案 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()
。