Express.js / Passport.js:req.user存储在哪里?

时间:2013-11-25 20:48:04

标签: mongodb heroku express redis passport.js

我正在开发一个将部署到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()中从那里获取?

1 个答案:

答案 0 :(得分:10)

req.user是一个便利属性,是req.session.user的别名,存储在redis中。因此,对于启用会话的请求,会话数据从redis加载,然后为方便起见,req.user设置为与req.session.user相同,然后您的代码运行并响应请求,并且一旦发送响应,这些内存版本就有资格进行垃圾回收。 redis中的副本一直存在,直到会话到期。

  

如果是这样,是否可以将原始用户数据转储到serializeUser()中的Mongo数据库,然后在deserializeUser()中从那里获取?

是的,如果您想将用户数据用作应用程序数据的一部分(这是典型的),这就是一般模式。因此,最终mongo将拥有所有已登录的用户,并且redis将为每个用户提供当前活动的会话,并且内存将使应用程序正在处理来自此时的请求的每个用户。< / p>