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

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

在同一个文件 both/routes.js 中,我有一个简单的服务器端路由,可以将 pdf 呈现到屏幕上,如果我删除 onBeforeAction 代码,该路由就可以工作(pdf 呈现到页面):

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 问题的主要答案是 “您在 Route.onBeforeAction 中使用 Meteor.user() 但它无权访问此信息”,而当 “您的浏览器发出 GET/POST 请求” [服务器端路由?],“到服务器它没有关于用户身份验证状态的任何信息。”

根据同一个 SO 回答者的说法,解决方案是 “找到一种替代方法来验证用户”,其中一种方法是使用 “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 代码由于某种原因无效。

我的问题

Question 1: Setting/getting the cookies in the manner depicted in the SO Cookies technique doesn't seem to work for me, does this technique still work in '15?

Question 2: Using cookies, how do I inform the server of the authentication state based on these cookies? Or, another way, How does adding the cookie check in my server side route "inform" the server about the user? I could check for anything in this route really; I could reject any user, but somehow the server needs to "know" about the user logged in right?

Question 3: Is cookies the best way to go about this, or is there a simpler way to achieve the same thing?

Side Question: I've seen a few places where middle ware is used for server side routes, for example:

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

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

But none of these examples had security inside, will using middle ware in this way allow me to get around my problem?

最佳答案

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

if (Meteor.isClient) {
  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'}
  );
}

Router.route('/pdf-server', function() {
  ...
}, {where: 'server'});

关于javascript - Iron Router 和 Meteor 中的服务器端路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27714618/

相关文章:

javascript - 将 CouchDB 与 Node.js 库一起使用

javascript - 如何在 javascript 中使用 CryptoJS

javascript - 如何将对象传递给 Mocha 测试

java - 将 Cookie 的安全设置为 true

http - cookie "metadata"(expires, path,...) 是否传输到服务器?

javascript - Angular + bootstrap-ui,检查当前选项卡是否已经激活

javascript - OpenAI GPT-3 API 错误 : "This model' s maximum context length is 2049 tokens"

javascript - Jssor Slider 如何将箭头添加到缩略图图库

javascript - hapi.js Cors 飞行前不返回 Access-Control-Allow-Origin header

c# - MVC4 不在浏览器中保存 cookie