Node.js Express + Passport + Cookie会话n> 1个服务器

从护照文档:

在典型的Web应用程序中,用于authentication用户的凭证只会在login请求期间传输。 如果validation成功,会话将通过在用户浏览器中设置的cookie来build立和维护。

每个后续请求将不包含凭据,而是标识会话的唯一Cookie。 为了支持login会话,Passport将序列化和反序列化会话中的用户实例。

因此,鉴于身份validation是在客户端的浏览器中维护的,我应该能够将Web服务器扩展到大于1(每个服务器使用相同的数据库),并且Passport将用户从存储在cookie中的ID反序列化,而不pipe服务器是否看到用户之前。 如果服务器之前见过用户,但没有cookie,我希望Passportauthentication失败,但是我甚至不能用n> 1的服务器获得这么多。

1服务器进程,护照工作正常:

服务器或多或less是两个服务器上的文档的完整文档(经过大量的试验,连接参考文献等):

app.configure(function() { app.use(express.static('public')); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.session({ secret: 'keyboard cat' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); }); 

当用户login成功时,在我返回HTTP请求之前,我logging了req.userreq.session

 console.log(req.user); console.log(req.session); res.send(200, req.user); // {"cookie":{ // "originalMaxAge":null, // "expires":null, // "httpOnly":true, // "path":"/" // }, // "passport":{"user":"ID"}} 

当HTTP请求返回时,Web应用程序请求/并期望服务器从传递的cookie中设置具有ID ID req.user

 passport.deserializeUser(function(req, user_id, cb) { console.info('Passport deserializing user: ' .concat(user_id)); console.log(req.user); console.log(req.session); // ... // cb(null, user); }); 

在运行1台服务器的情况下,该日志logging为

 Passport deserializing user: ID undefined undefined 

在callbackcb(null, user) ,在我返回请求之前立即loggingreq.userreq.session ,看看我期望的是什么!

现在,运行n> 1个服务器 ,让我们说2,如果Web应用程序请求/从服务器2,并期望它从传递的cookie(最初通过login到服务器1设置)设置ID为ID ID req.user ,我不'你甚至可以看到所谓的反序列化函数! 当我将日志logging添加到HTTP路由的开头(在中间件之后)时:

 console.log(req.user); console.log(req.session); 

我懂了:

 undefined // {"cookie":{ // "originalMaxAge":null, // "expires":null, // "httpOnly":true, // "path":"/" // }, // "passport":{}} 

…告诉我cookies有什么东西了,但是什么? 两个服务器进程在同一个DNS后面的Heroku上。 我已经阅读了各种关于需要一些“共享会话”存储的差异…但这是一个cookie在客户端的浏览器级别。 请帮忙! Express是最新的3.X和护照是2.1。

       

网上收集的解决方案 "Node.js Express + Passport + Cookie会话n> 1个服务器"

该cookie不包含会话数据,它只包含会话ID。 使用这个ID,您的Express应用程序将从它的会话存储中获取相关的会话数据。 因为在调用app.use(express.session({ secret: 'keyboard cat' }));时你并没有定义商店app.use(express.session({ secret: 'keyboard cat' })); 您正在使用不在进程之间共享的内置内存存储。

所以,安装任何使用数据库的会话存储,例如。 connect-mongo for MongoDB。

作为拥有服务器端数据库的替代scheme,您可以将会话数据存储在encryption的cookie中,例如Mozilla所使用的cookie: https : //github.com/mozilla/node-client-sessions 。 这比任何服务器端数据库都要大,但是你必须保持cookie的大小合理。 如果我有更多的时间,我会给你写一个演示,但现在我只是把这个问题放回去。