2013-11-25 149 views
4

我正在开发一个将要部署到Heroku的Web应用程序。Express.js/Passport.js:req.user存储在哪里?

我选择使用Node.js堆栈,因为我厌倦了“传统”web框架。我正在设计Express.js上的应用程序。我发现它比较高效和直观。 Django或Grails。

因此,网络应用程序将具有访客和经过身份验证的用户的功能。随着应用程序部署到Heroku,这是一个云平台服务,应用程序不能在服务器内部存储任何内部状态,因为Heroku的负载均衡器和惯例是一般的。事实上,拥有内部状态在分布式环境中也是不好的设计。

我的本地开发设置有一个Redis实例(用于存储会话)和一个MongoDB实例(用于存储用户数据,例如Facebook用户详细信息)。我使用Passport.js和护照-Facebook来处理认证。目前,我只实现了Facebook身份验证,至少在本地运行良好。

问题是我不确定也没有看到有关Express/Passport如何奇迹般地填充对象的任何地方。我对此有点怀疑,感觉它存储在服务器的内存中。

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()中获取它?

回答

5

req.user是一个便利属性,它是req.session.user的别名,存储在redis中。因此,对于启用会话的请求,会话数据是从redis中加载的,然后req.user被设置为与req.session.user相同,然后您的代码将运行并响应请求,并且这些内存中的版本符合垃圾一旦收到回复就收集。直到会话过期,redis中的副本才能存活。

如果是这样,是否将解决方案将原始用户数据转储到serializeUser()中的Mongo数据库中,然后从deserializeUser()中获取它?

是的,如果您想将用户数据用作应用程序数据的一部分(这是典型的),那么这就是一般模式。所以最后mongo会让每一个曾经登录过的用户都知道,而且redis会让每个用户都拥有一个当前活动的会话,并且内存将让每个用户都处于这个瞬间处理请求的过程中。

+0

作为Redis的noobie,我已经查询密钥,在Redis的CLI,但并没有碍着GET命令实际访问的重点内容。现在我看到Redis存储的是与deserializeUser()相同的JSON。感谢您的回复。 – tukkajukka

+0

我知道这个评论是在3年前发布的,但作为一个类似的Redis noob,我只是犯了完全相同的错误,这对我非常有帮助,谢谢。 – BML91