如何在Heroku上使用多个dyno的node-openid?

我正在尝试使用node-openid (通过passport-google )来使用他们的Google凭证对我的用户进行身份validation。 它在我的开发机器上工作正常,但是当我用2个dynos将它部署到Heroku时,它在一个dyno处理整个OpenID对话时起作用,当对话在一个dyno上开始并在第二个时完成时失败。 在这种情况下,我得到以下错误:

2013-01-15T15:18:24+00:00 app[web.2]: Failed to verify assertion (message: Invalid association handle) 2013-01-15T15:18:24+00:00 app[web.2]: at Strategy.authenticate.identifier (/app/node_modules/passport-google/node_modules/passport-openid/lib/passport-openid/strategy.js:143:36) ... 

什么是正确的方式来处理这个? 我应该将会话状态保存在数据库中,以便两个dynos都可以访问它吗?

更新:

这里是我用来解决问题的代码,通过在MongoDB中存储关联。

 var GoogleStrategy = require('passport-google').Strategy; // We have to save the OpenID state in the database so it's available to both // dynos. db.collection('OpenID').ensureIndex({expires: 1}, {expireAfterSeconds: 0}, function(err, result) { if (err) { throw new Error('Error setting TTL index on OpenID collection.'); } }); // Use the GoogleStrategy within Passport. // Strategies in passport require a `validate` function, which accept // credentials (in this case, an OpenID identifier and profile), and invoke a // callback with a user object. strategy = new GoogleStrategy({ returnURL: 'http://localhost:3000/auth/google/return', realm: 'http://localhost:3000/' }, function(identifier, profile, done) { // asynchronous verification, for effect... process.nextTick(function () { // To keep the example simple, the user's Google profile is returned to // represent the logged-in user. In a typical application, you would want // to associate the Google account with a user record in your database, // and return that user instead. profile.identifier = identifier; return done(null, profile); }); } ); strategy.saveAssociation(function(handle, provider, algorithm, secret, expiresIn, done) { db.collection("OpenID").insert({ handle: handle, provider: provider, algorithm: algorithm, secret: secret, expires: new Date(Date.now() + 1000 * expiresIn) }, done); }); strategy.loadAssociation(function(handle, done) { db.collection("OpenID").findOne({handle: handle}, function (error, result) { if (error) return done(error); else return done(null, result.provider, result.algorithm, result.secret); }); }); 

您应该检查node-openid README中的Storing关联状态部分。 默认情况下,会话状态存储在内存中的单个dynos,这是什么导致你的问题。

覆盖saveAssociation()loadAssociation() mixins以使用您的应用程序当前使用的任何后备存储。 在passport-openid源代码中有更多的文档 。