首页 > 解决方案 > MongoDB Stitch 在 Facebook 登录尝试期间双重编码重定向 URI 破坏登录过程?

问题描述

我正在尝试为基于 Web 的 Todo 应用程序使用 MongoDB Stitch 示例教程。我在 Ubuntu 18.04 Bionic Beaver Linux 站上使用 Node.JS v10.14.2。

当我尝试使用 Facebook 登录时,登录过程失败,Facebook 抱怨 Stitch 服务器生成的重定向 URL 未列入白名单,因此在尝试使用 OAuth 登录 Facebook 时被拒绝。该 URL 是在此 Node 模块中的此代码块期间生成的:

node_modules/mongodb-stitch-browser-core/dist/cjs/core/auth/internal/StitchAuthImpl.js

这是生成启动登录过程的 URL 的代码。它调用 Stitch 服务器,Stitch 服务器生成正确的 URL 以要求 Facebook 登录用户。请注意,我确实修改了代码,但只是为了向我展示getAuthProviderRedirectRoute()调用正在生成的值。没有进行其他更改。

   StitchAuthImpl.prototype.loginWithRedirect = function (credential) {
        var _this = this;
        var _a = this.prepareRedirect(credential), redirectUrl = _a.redirectUrl, state = _a.state;
        this.requestClient.getBaseURL().then(function (baseUrl) {
            // ROS: We want to see the URL being created - ESM.
            let replaceUrl = baseUrl +
                _this.browserAuthRoutes.getAuthProviderRedirectRoute(credential, redirectUrl, state, _this.deviceInfo);
            _this.jsdomWindow.location.replace(replaceUrl);
        });
    };

下面是replaceUrl的值,它显示了在 Facebook 登录过程的初始阶段生成的 URL:

   replaceUrl = https://stitch.mongodb.com/api/client/v2.0/app/my_stitch_app/auth/providers/oauth2-facebook/login?redirect=http://localhost:8001/&state=<<redacted>>&device=<<redacted>>

Stitch 为 OAuth Facebook 登录握手的开始生成此 URL。从代码中可以看出,此 URL 已加载到浏览器的位置。然后,缝合服务器为 OAuth 握手的下一阶段生成 URL。我从它生成并将控制权转移到的 URL 中摘录了redirect_uri查询参数,如下所示:

redirect_uri%3Dhttps%253A%252F%252Fstitch.mongodb.com%252Fapi%252Fclient%252Fv2.0%252Fauth%252Fcallback

然后我手动解码了重定向 URI,因为它看起来不对。如果您查看上面显示的redirect_uri查询参数,您将看到 OAuth 回调 URI 已使用encodeUri()方法进行了双重编码。这会导致 Facebook OAuth 服务器拒绝回调 URI,因为在解码后,它看起来像下面显示的DECODED ONCE标签 旁边显示的 URL 。

这会导致 OAuth 握手失败,因为它与您在下面看到的标有标签 "DECODED AGAIN" 的 URL 不匹配

该值是我按照 MongoDB Stitch 教程的指示在“有效 OAuth 重定向 URI”部分的 Facebook OAuth“客户端 OAuth 设置”页面中输入的值。由于 URL 已被双重编码,重定向 URI 解码一次后,与“DECODED AGAIN”值不匹配,登录过程失败。显然,我可以将“DECODED ONCE”值添加到白名单 URL 列表中,但这只会解决问题,因为它应该看起来像“DECODED AGAIN”中完全解码的值。

解码一次

redirect_uri=https%3A%2F%2Fstitch.mongodb.com%2Fapi%2Fclient%2Fv2.0%2Fauth%2Fcallback

再次解码

redirect_uri=https://stitch.mongodb.com/api/client/v2.0/auth/callback

概括地说,当 Facebook 被要求使用 Stitch 生成的 URL 登录用户时,如下所示,Facebook 失败了,错误消息如下所示:

https://www.facebook.com/login.php?skip_api_login=1&api_key=<<redacted>>&kid_directed_site=0&app_id=<<redacted>>%26redirect_uri%3Dhttps%253A%252F%252Fstitch.mongodb.com%252Fapi%252Fclient%252Fv2.0%252Fauth%252Fcallback

脸书错误

URL Blocked

This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings. Make sure Client and Web OAuth Login are on and add all your app domains as Valid OAuth Redirect URIs.

我已经搜索了 MongoDB Stitch 控制面板,但我没有看到任何可能输入的内容会导致回调 URL 被 Stitch 传递给 Facebook,以进行双重编码。谁能告诉我什么可能导致这种不良行为以及如何解决这个问题?

标签: node.jsmongodbfacebookoauthmongodb-stitch

解决方案


感谢您的详细解释。我尝试重现您的问题,但我能够成功登录 Facebook。

我还检查了 Stitch 服务器在重定向到 Facebook 时生成的 URL,它与您在帖子中的双编码 URI 完全相同。这意味着此行为是预期的,不应影响登录流程。

如果您查看完整的 URL,您会看到主 url(从“ https://www.facebook.com/login.php ”开始)有一个名为“next”的查询参数。“next”参数是一个 URL,因此需要进行 URL 编码。传递给“next”的这个 URL 有“redirect_uri”参数,它也是一个 URL,所以它也需要进行 URL 编码。由于这是 URL 中的 URL 中的 URL,这就是您看到双重编码的原因。

我用新行上的每个参数格式化了 URL,每个子 URL 旨在帮助演示这一点:

https://www.facebook.com/login.php
    ?skip_api_login=1
    &api_key=<redacted>
    &kid_directed_site=0
    &app_id=<redacted>
    &signed_next=1
    &next=https%3A%2F%2Fwww.facebook.com%2Fdialog%2Foauth
        %3Faccess_type%3Doffline
        %26client_id%<redacted>

        // this is the double encoded URL
        %26redirect_uri%3Dhttps%253A%252F%252Fstitch.mongodb.com%252Fapi%252Fclient%252Fv2.0%252Fauth%252Fcallback

        %26response_type%3Dcode
        %26scope%3Demail%2Bpublic_profile
        %26state%3D<redacted>
        %26ret%3Dlogin
        %26fallback_redirect_uri%<redacted>
    &cancel_url=https%3A%2F%2Fstitch.mongodb.com%2Fapi%2Fclient%2Fv2.0%2Fauth%2Fcallback
        %3Ferror%3Daccess_denied
        %26error_code%3D200
        %26error_description%3DPermissions%2Berror
        %26error_reason%3Duser_denied
        %26state%3D<redacted>
    &display=page&locale=en_US

为了让 Facebook 登录正常工作,我将确保以下几点:

  • 在 Facebook 控制台中,确保将此 URL 添加到“有效 OAuth 重定向 URI”列表中:

  • 在 Stitch 控制台中,确保您的应用程序 URL 包含在 Facebook 提供程序的“重定向 URI”列表中。这应该包括任何尾随斜杠。

  • 在您的应用程序代码中,确保您在点击重定向 URL 时调用以下 JS 代码。这允许 Stitch 客户端 SDK 获取 Stitch 服务器执行的 OAuth2 流的结果:

  if (yourStitchClient.auth.hasRedirectResult()) {
    return yourStitchClient.auth.handleRedirectResult().then(user => {
        console.log("Authenticated as user: " + user);
    });
  }

查看https://docs.mongodb.com/stitch/authentication/facebook/以获取有关这些步骤的更多说明。

如果您在完成上述步骤后仍然无法使其正常工作,请告诉我,我会尽力帮助您调试问题。


推荐阅读