首页 > 解决方案 > Facebook 检测到“应用程序”未使用安全连接来传输信息

问题描述

我有一个 nodejs 应用程序来使用 Facebook 对用户进行身份验证。该应用程序是使用 Heroku 部署的。它适用于 localhost,但不适用于已部署的站点 URL。我该如何解决这个问题

在此处输入图像描述

passport.use(new FacebookStrategy({
    clientID: keys.facebook.clientID,
    clientSecret: keys.facebook.clientSecret,
    callbackURL: "/auth/facebook/callback",
  },
  function(accessToken, refreshToken, profile, done) {
    const { id, first_name, last_name ,name} = profile._json;
    const userData = {
      facebook_id : id,
      first_name : first_name,
      last_name : last_name,
      username : name
    };
    userModel.findOne({facebook_id:id}).then((user)=>{
        if(!user)
            new userModel(userData).save().then((newUser)=>{
                done(null,newUser)
            });
        else
            done(null,user)
    })
  }
));
app.get('/auth/facebook', passport.authenticate('facebook'))

app.get("/auth/facebook/callback",passport.authenticate("facebook", {
      successRedirect: "/success",
      failureRedirect: "/fail"
    })
);

Heroku 日志

2021-04-24T09:58:58.154550+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
2021-04-24T09:58:58.154565+00:00 app[web.1]: at Timeout.<anonymous> (/app/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:185:20)
2021-04-24T09:58:58.154566+00:00 app[web.1]: at listOnTimeout (internal/timers.js:554:17)
2021-04-24T09:58:58.154567+00:00 app[web.1]: at processTimers (internal/timers.js:497:7)
2021-04-24T09:58:58.154668+00:00 app[web.1]: (node:4) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
2021-04-24T09:59:17.992947+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/auth/facebook/callback?code=AQCWsZz7kdnjlF6b-4UltHiCo8nvktLXI8pwtEm65SO6DbH78h6dzTvygqZkUE2eg9WVufXyLdXUgX58_65TTb54zPWXN1sdTBTMltjO3nm_49XeWBqkcYa3qLcXUV_LwS2H_v2DpMbTTpcL5o430yHsdC3J4SF4VsXEV0tQ2E6wYgh9zMVBL-b7Omj8n_vIvLPqMlAnccP8PFMZOeV8UV0b0DovUNL8dd930aL12-x1RNdlw_yvq7G3TqpKXCq64Ny-hkNsTeSRSR0qEpiWUoC_afLMi-VoU1AiFp3gCfsWSumfQcsDWvwAv1eJDY9T48b6XP0i_u8f7FnQySExnrFl" host=authenticate-backend.herokuapp.com request_id=244f274e-ae42-4560-9f8f-078dbf987f6f fwd="116.206.223.233" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0 protocol=https
2021-04-24T10:04:39.435159+00:00 heroku[router]: at=info method=GET path="/" host=authenticate-backend.herokuapp.com request_id=d30d85eb-9137-43c5-8d5f-b6bd300094f4 fwd="116.206.223.233" dyno=web.1 connect=1ms service=2ms status=304 bytes=181 protocol=https

标签: node.jsherokufacebook-graph-apifacebook-login

解决方案


这听起来您的问题与应用程序在代理后面运行时重建 facebook 策略的完整回调 url 的方式有关。

在您的代码指定的相对回调 url 的情况下,facebook 策略实际上最终会调用以下函数来获取完整的 url - 稍微简化了一些基本位:

function originalURL(req, options) {
    var trustProxy = req.app.get('trust proxy')) ? true : false;

    var isConnectionSecure = req.connection.encrypted || (trustProxy && 'https' == req.headers['x-forwarded-proto'].split(/\s*,\s*/)[0])
    var protocol = isConnectionSecure ? 'https' : 'http'
    // ...

    return protocol + '://' + host + path;
};

本质上,它试图了解传入请求是否通过安全通道传输。

  • 它首先查看当前连接是否实际加密。
  • 如果不是,它会检查请求是否由受信任的代理转发,其中客户端和代理之间的连接是加密的。

只有在其中任何一种情况下,回调 url 的协议才会设置为 https。

据我所知,Heroku 使用代理在内部使用常规 http 重定向流量,因此您需要设置您的应用程序以信任它。

app.enable('trust proxy')

正如我在聊天中提到的,后来在 mongoose 的评论中提出的另一个问题与提出的问题完全不同。


推荐阅读