【问题标题】:PassportJS callback switch between http and httpsPassportJS 回调在 http 和 https 之间切换
【发布时间】:2014-01-11 10:45:02
【问题描述】:

现在,当我访问我的页面 https://example.com 并单击登录时,它转到 https://example.com/auth/facebook,然后它会处理 facebook 的内容并最终回调 http://example.com/auth/facebook/callback。我似乎无法让它使用 https 方案进行回调(但仅当请求周期在 https 中开始时)。

现在,当通过 https iframe(facebook 画布应用程序)查看时,我收到错误

[已屏蔽] 页面位于 'https://apps.facebook.com/example/?fb_source=notification&ref=notif&notif_t=app_notification' 通过 HTTPS 加载,但运行不安全的内容 'http://example.com/auth/facebook/callback?code=AQD5TUeTP…yXC0ZM8S45V2iTta629IaquCpAqVUbhAvNCFveaDBlbKg4J4#=': 此内容也应通过 HTTPS 加载。

passport.use(new FacebookStrategy({
    clientID: process.env.FB_CLIENT,
    clientSecret: process.env.FB_SECRET,
    callbackURL: "/auth/facebook/callback",
    profileFields: ['id']
},...

app.get('/auth/facebook',
  passport.authenticate('facebook', {
    scope: ["read_stream"]
  })
);

app.get('/auth/facebook/callback',
  passport.authenticate('facebook', {
  failureRedirect: '/#'
}),
function(req, res) {
  res.redirect('/#');
});

我在 heroku 上运行它,它处理 https 上的详细信息。

编辑 显然,节点提供了 req.connection.encrypted 以及有关请求是否为 https 的信息。由于我在处理节点之前的所有 https 的 nginx 后面的 heroku 上运行,因此 req.connection.encrypted 将始终未定义。

还是不知道怎么解决。

【问题讨论】:

  • passport oauth2 策略使用 req.connection.encrypted 来检查它是否处于安全连接中。你能试试看它的输出吗?也许您实际上是在不安全的连接下运行的。
  • 乔纳斯,这是一个很好的评论,感谢您为我指明了正确的方向。我在这里找到了一个帖子:groups.google.com/forum/#!topic/express-js/Bm6yozgoDSY,因为 SSL 是由 Heroku 上的 nginx 处理的,所以 req.connection.encrypted 始终是“未定义的”。关于如何解决这个问题的任何想法?
  • 乔纳斯,那条评论让我想出了如何解决这个问题(挖掘护照代码)。如果你能做出回答,我会奖励它的声望点。欢迎您接受我发布的答案(在这种情况下,我将在之后删除我的答案)。
  • 太棒了!我做了一个回答,试图将所有信息放在一起。

标签: javascript node.js facebook passport.js


【解决方案1】:

对不起,这个答案有点蹩脚,我不能根据事情的性质给你一个具体的答案。

我相信您在 facebook api 控制台中的回调 url 可能是 http,如果您将其更改为 https 它应该可以工作。

如果这不起作用,您可以尝试将 callbackURL 更改为完整的 url ("https://example.com/auth/facebook/callback")

【讨论】:

  • 关于如何根据请求方案/url 动态生成完整 url 回调的任何想法?这是我考虑了一段时间的解决方案之一,但我无法访问 req 那里,所以我无法弄清楚这些东西。
  • @EliWhite,不,我认为你不能。另外,请参阅我的更新答案
【解决方案2】:

Nginx 处理 Heroku 上的所有 HTTPS,因此节点永远不会看到 req.connection.encrypted 是未定义以外的任何内容。通过挖掘 passportjs 存储库,我发现有一个检查应用程序是否启用了“信任代理”。要解决此问题,请添加行

app.enable("trust proxy");

到您的快递服务器。

【讨论】:

    【解决方案3】:

    我查看了 Passport Oauth2 策略代码并检查它是否使用 req.connection.encrypted 来检查它是否处于安全连接中。 它还会检查代理,以防服务器代码在代理之后运行。如果您知道自己支持代理,则可以告诉护照信任代理。

    似乎由于 SSL 是由 Heroku 上的 nginx 处理的,所以 req.connection.encrypted 总是“未定义”。 (groups.google.com/forum/#!topic/express-js/Bm6yozgoDSY) Nginx 处理 Heroku 上的所有 HTTPS,因此节点永远不会看到 req.connection.encrypted 是“未定义”以外的任何内容。

    要解决问题,您必须告诉护照信任代理添加行

    app.enable("trust proxy");
    

    到您的快递服务器。

    【讨论】:

    • 我也没有在 nginx proxy_set_header X-Forwarded-Proto $scheme; 中指定标头
    【解决方案4】:

    我还了解到,我们可以通过向 googleStrategy 添加另一个名为“proxy:true”的属性来完成同样的事情,如下所示:

    passport.use(新的 GoogleStrategy({ 客户端ID:keys.googleClientID, clientSecret:keys.googleClientSecret, callbackURL: '/auth/google/callback', 代理:真 }

    【讨论】:

      【解决方案5】:

      尝试 passport-facebook 和 passport-disqus 我也遇到了同样的问题,谷歌没有问题,因为它允许你使用 http 进行回调,但其他人没有。

      设置"app.enable("信任代理");"在主应用文件上解决了!

      【讨论】:

        猜你喜欢
        • 2011-10-20
        • 1970-01-01
        • 2012-08-17
        • 2010-11-09
        • 1970-01-01
        • 2012-05-14
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        相关资源
        最近更新 更多