Iron Router和Meteor中的服务器端路由

时间:2014-12-31 00:32:54

标签: javascript node.js cookies meteor iron-router

转发

似乎在Meteor中,我们不能调用服务器端路由将文件呈现到页面,而不需要从我们正常的工作流程中解决某些问题,而不是我读过的有关服务器端路由的内容。我希望我对此有所不妥,并且有一种简单的方法来实现我想做的事情......

**对不起,如果这有点长,但我认为在这种情况下提供更多背景和背景是有道理的**

软件/版本

我正在使用最新的Iron Router 1. *和Meteor 1. *并且开始,我只是使用帐户密码。

背景/背景

我有一个onBeforeAction,根据用户是否登录,只需将用户重定向到欢迎页面或主页:

两者/ routes.js

Router.onBeforeAction(function () {
  if (!Meteor.user() || Meteor.loggingIn())
    this.redirect('welcome.view');
  else
    this.next();
  }
  ,{except: 'welcome.view'}
);

Router.onBeforeAction(function () {
  if (Meteor.user())
    this.redirect('home.view');
  else
    this.next();
  }
  ,{only: 'welcome.view'}
);

在同一个文件中,两个/ routes.js,我都有一个简单的服务器端路由,它将pdf呈现给屏幕,如果我删除onBeforeAction代码,路由可以正常工作(pdf呈现给页面): / p>

Router.route('/pdf-server', 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'});

服务器路由

上抛出异常

除此之外,当我将上述服务器端路由添加到文件并使用路由/ pdf-server时,我得到一个例外,同时保留onBeforeAction代码。

可以在此处找到对例外的见解:SO Question on Exception

异常的解决方案

以上SO问题中答案的主要要点是"You use Meteor.user() in your Route.onBeforeAction but it has no access to this information",何时,"your browser make a GET/POST request" [服务器端路由?],"to the server it doesn't have any information regarding the user's authentication state."

解决方案,根据相同的SO回答者"find an alternative way to authenticate the user,",一种方法是使用"cookies'"

所以,继续这一点,我找到了另一个SO答案(与之前一样的回答者),其中列出了设置和获取cookie的方法:SO Cookies technique

**因此,总而言之,为了允许服务器端路由,建议我使用cookie而不是Meteor.userId()或this.userId。 **

添加了Cookie相关代码

所以我将以下代码添加到我的项目中: 客户机/ main.js

Deps.autorun(function() {
    if(Accounts.loginServicesConfigured() && Meteor.userId()) {
        setCookie("meteor_userid",Meteor.userId(),30);
        setCookie("meteor_logintoken",localStorage.getItem("Meteor.loginToken"),30);
    }
}); 

在我的服务器端路由中,我将路由更改为:

两者/ routes.js

Router.route('/pdf-server', function() {
  //Parse cookies using get_cookies function from : https://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-server
  var userId = get_cookies(req)['meteor_usserid'];
  var loginToken = get_cookies(req)['meteor_logintoken'];
  var user = Meteor.users.findOne({_id:userId, "services.resume.loginTokens.token":loginToken});
  var loggedInUser = (user)?user.username : "Not logged in";

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

但是这不能按预期工作,因为某些原因,setCookie代码无效。

我的问题

  

问题1:以图中所示的方式设置/获取cookie   SO Cookies technique似乎不适合我,这样做   技术仍然在' 15?

     

问题2:使用cookies,如何通知服务器   基于这些cookie的身份验证状态?或者,另一种方式,如何在我的服务器中添加cookie检查   旁路"通知"关于用户的服务器?我可以检查一下   这条路线的任何东西真的;我可以拒绝任何用户,但不知何故   服务器需要知道"关于用户登录对吗?

     

问题3:饼干是解决这个问题的最佳方式,还是有问题   更简单的方法来实现同样的目标?

     

方面问题:我已经看过一些使用中间件的地方   服务器端路由,例如:

WebApp.connectHandlers.stack.splice(...);

WebApp.connectHandlers.use(function(...) ...);
  

但是这些例子中没有一个具有安全性,将使用中间件   这样可以让我解决我的问题吗?

1 个答案:

答案 0 :(得分:8)

您的服务器端路由正在运行全局onBeforeAction代码(它在共享目录中定义),因为服务器路由是简单的REST端点,它们不了解用户身份验证信息(即{{1不起作用)。解决方案是使用Meteor.user()包装特定于客户端的onBeforeAction调用,或者只是将该代码移动到Meteor.isClient目录下。例如:

client