【问题标题】:Does passport.js require session affinity when deployed on multiple node.js instances部署在多个 node.js 实例上时,passport.js 是否需要会话亲和性
【发布时间】:2013-06-20 21:34:48
【问题描述】:

在多个 Node.js 实例上部署时,passport.js 是否需要会话亲和性?当我使用会话亲和性时,身份验证适用于多个实例(在负载均衡器后面)。我使用 redis 作为会话存储。但是,当不使用会话关联时,passport.js 会失败,并出现以下错误。对于单个实例,它始终有效。有什么方法可以让 passport.js 在没有会话关联的情况下工作。

    500 Failed to verify assertion (message: Invalid association handle)

    at Strategy.authenticate.identifier (node_modules/passport-google/node_modules/passport-openid/lib/passport-openid/strategy.js:184:36)
    at _verifyAssertionData (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1053:12)
    at _verifyAssertionAgainstProvider (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1178:14)
    at _checkSignatureUsingAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1229:14)
    at Object.openid.loadAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:111:5)
    at _checkSignatureUsingAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1221:10)
    at _checkSignature (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1211:5)
    at _verifyAssertionAgainstProvider (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1174:3)
    at _verifyDiscoveredInformation node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1145:16)
    at openid.discover (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:668:7)

使用护照的代码sn-p:

app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.query());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser()); 
app.use(express.session({ key: 'JSESSIONID', secret: '****', cookie : {httpOnly:false, 
   maxAge: 5*60*1000, path: '/'},
    store: new RedisStore({ prefix: 'sid:', client: redisClient })
                    }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.get('/auth/google', passport.authenticate('google'));
app.get('/auth/google/return', 
      passport.authenticate('google', { successRedirect: '/success',
                                        failureRedirect: '/login' }));

我还有 serializeUser 和 deserializeUser,它们使用 redis 存储来存储/检索用户对象 - 但是当身份提供者重定向回回调 URI 时会发生此错误。我在 AppFog 中部署我的应用程序并使用 JSESSIONID cookie 密钥设置会话亲和性(这就是 cloudfoundry 负载均衡器的工作方式)。如果我使用任何其他密钥(这意味着会话关联已关闭),则 passport.js 会引发错误。

【问题讨论】:

  • 你应该能够在没有亲和力的情况下运行。我认为如果我们能看到您如何使用 redis 来存储和共享会话会有所帮助。相关的代码行可能会有所帮助。
  • 我已经添加了代码 sn-p 以及一些更简短的情况说明。任何帮助将不胜感激。
  • 另一个重要提示:facebook 和 twitter 提供程序在没有会话关联的情况下工作正常(它们都使用 OAuth)。 Google auth (OpenID) 会出现问题。有时它确实适用于谷歌 - 但我假设原始请求和重定向都由同一个实例处理。

标签: node.js session


【解决方案1】:

我想我已经解决了。有一个选项:可以传递给 GoogleStrategy 的“无状态”。我通过查看源找到了它:https://github.com/jaredhanson/passport-openid/blob/master/lib/passport-openid/strategy.js。因此,GoogleStrategy 实例化必须是:

new GoogleStrategy({
   returnURL: BASE + '/auth/google/return',
   realm: BASE + "/",
   stateless: true
}

感谢 Jared Hanson 实现了这样的选项! (希望它会在主站点上记录下来)。

【讨论】:

  • 这对 Heroku 上的多测功机应用很有帮助。使用 Mongo 作为会话存储时,我遇到了同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
  • 2017-05-17
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多