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