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

前锋

在meteor看来,我们不能调用服务器端路由来将文件呈现给页面,而没有从我们正常的工作stream程中进行某种处理,从我所读到的有关服务器端路由的一些方面。 我希望我错了,有一个简单的方法来实现我想要做的事情…

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

软件/版本

我正在使用最新的铁路路由器1. *和meteor1. *开始,我只是使用帐户密码。

背景/上下文

我有一个onBeforeAction,只要将用户redirect到欢迎页面或主页基础上,如果用户login或不是:

两者/ 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呈现到页面):

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

服务器路由抛出的exception

这是没有关系的,但是当我把上面的服务器端路由添加到文件中,并且在保持onBeforeAction代码到位的同时,使用路由/ pdf-server时,我得到一个exception。

洞察exception可以在这里find:所以对exception的问题

对例外的解决scheme

在上面的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回答者的解决scheme是"find an alternative way to authenticate the user,"方法"find an alternative way to authenticate the user," ,一种做法是使用"cookies'"

所以,继续下去,我find了另外一个答案(通过与以前相同的答案),在这里设置和获取cookie的方法概述如下: SO Cookies技术

**所以,总结一下,为了允许服务器端路由,build议我使用cookies而不是像Meteor.userId()或this.userId。 **

与Cookie相关的代码添加

所以我将下面的代码添加到我的项目中:client / 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:以SOcookies技术所描述的方式设置/获取cookies似乎不适用于我,这种技术在15年仍然有效吗?

问题2:使用cookies,如何根据这些cookie通知服务器身份validation状态? 或者,另一种方式,如何添加cookie检查我的服务器端路由“通知”服务器关于用户? 我真的可以检查这条路线上的任何东西; 我可以拒绝任何用户,但不知何故服务器需要“知道”login用户的权利?

问题3:cookies是最好的方式去做,或者有一个简单的方法来实现相同的事情?

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

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

但是这些例子都没有内部的安全性,这样使用中间件会让我解决我的问题吗?

您的服务器端路由正在运行全局onBeforeAction代码(它在共享目录中定义),由于服务器路由是不理解用户身份validation信息的简单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'});