我正在开发一个将部署到Heroku的Web应用程序。
我选择使用Node.js堆栈,因为我厌倦了“传统”的Web框架。我在Express.js上设计应用程序。与以下相比,我发现它非常高效和直观。 Django或Grails。
因此,网络应用程序将为访客和经过身份验证的用户提供功能。当应用程序部署到Heroku(一个云平台服务)时,由于Heroku的负载平衡器和实践,应用程序不能在服务器内部存储任何内部状态。事实上,在分布式环境中拥有内部状态也是糟糕的设计。
我的本地开发设置有一个Redis实例(用于存储会话)和一个MongoDB实例(用于存储用户数据,例如Facebook用户详细信息)。我使用Passport.js和 passport-facebook 来处理身份验证。目前,我只实施了Facebook身份验证,至少在本地工作正常。
问题是我不确定我是否也读过有关Express / Passport如何神奇地填充 req.user 对象的内容。我对此有点怀疑,感觉就像存储在服务器的内存中一样。
passport.serializeUser(function(user, done) {
console.log(
"This outputs a complete" +
"User Profile object when the user logs in.",
user);
done(null, user);
});
passport.deserializeUser(function(obj, done) {
console.log(
"And this too, but I'm afraid that" +
"obj comes from memory.",
obj);
done(null, obj);
});
Passport.js documentation并没有很好地说明这一点。我的猜测是serializeUser()从Facebook获取用户,但是deserializeUser()从内存中获取它?
如果是这样,是否可以将原始用户数据转储到serializeUser()中的Mongo数据库,然后在deserializeUser()中从那里获取?
答案 0 :(得分:10)
req.user
是一个便利属性,是req.session.user
的别名,存储在redis中。因此,对于启用会话的请求,会话数据从redis加载,然后为方便起见,req.user
设置为与req.session.user
相同,然后您的代码运行并响应请求,并且一旦发送响应,这些内存版本就有资格进行垃圾回收。 redis中的副本一直存在,直到会话到期。
如果是这样,是否可以将原始用户数据转储到serializeUser()中的Mongo数据库,然后在deserializeUser()中从那里获取?
是的,如果您想将用户数据用作应用程序数据的一部分(这是典型的),这就是一般模式。因此,最终mongo将拥有所有已登录的用户,并且redis将为每个用户提供当前活动的会话,并且内存将使应用程序正在处理来自此时的请求的每个用户。< / p>