MongoDB Stitch дважды кодирует перенаправление URI при попытке входа Facebook, нарушая процесс входа в систему?

#node.js #mongodb #facebook #oauth #mongodb-stitch

#node.js #mongodb #Facebook #oauth #mongodb-stitch

Вопрос:

Я пытаюсь использовать руководство по примерам MongoDB Stitch для веб-приложения Todo. Я использую Node.JS v10.14.2 на Ubuntu 18.04 Bionic Beaver Linux station.

Когда я пытаюсь войти в Facebook, процесс входа завершается неудачно, Facebook жалуется, что URL-адрес перенаправления, сгенерированный сервером Stitch, не занесен в белый список и, следовательно, был отклонен при попытке входа в Facebook с помощью OAuth. URL-адрес генерируется во время этого блока кода, найденного в этом модуле узла:

 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, которое показывает URL-адрес, сгенерированный на этом начальном этапе процесса входа Facebook:

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

Stitch генерирует этот URL-адрес для начала рукопожатия Facebook для входа в OAuth. Как вы можете видеть из кода, этот URL-адрес загружается в местоположение браузера. Затем сервер stitch генерирует URL-адрес для следующего этапа подтверждения OAuth. Я извлек аргумент запроса redirect_uri из URL, который он генерирует и передает управление, показанный здесь:

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

Затем я вручную расшифровал URI перенаправления, потому что он выглядел неправильно. Если вы посмотрите на аргумент запроса redirect_uri, показанный выше, вы увидите, что URI обратного вызова OAuth был дважды закодирован с помощью метода encodeURI(). Это приводит к тому, что Facebook OAuth-сервер отклоняет URI обратного вызова, потому что после декодирования он выглядит как URL, показанный рядом с меткой ДЕКОДИРОВАННЫЙ ОДИН РАЗ, показанной ниже.

Это приводит к сбою подтверждения OAuth, поскольку оно не соответствует URL-адресу, который вы видите ниже, помеченному меткой «ДЕКОДИРОВАНО СНОВА».

Это значение я ввел на странице Facebook OAuth «Настройки OAuth клиента» в разделе «Допустимые URI перенаправления OAuth», как указано в руководстве MongoDB Stitch. Поскольку URL-адрес был дважды закодирован, URI перенаправления при однократном декодировании не соответствует значению «ДЕКОДИРОВАНО СНОВА», и процесс входа завершается с ошибкой. Очевидно, что я мог бы добавить значение «ДЕКОДИРОВАНО ОДИН РАЗ» в список URL-адресов, внесенных в белый список, но это просто решило бы проблему, потому что оно должно выглядеть как полностью декодированное значение в «ДЕКОДИРОВАНО СНОВА».

РАСШИФРОВАНО ОДИН РАЗ:

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

СНОВА ДЕКОДИРОВАНО:

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

Напомним, что когда Facebook просят войти в систему пользователя с URL-адресом, сгенерированным Stitch, показанным ниже Facebook завершает процесс с сообщением об ошибке, также показанным ниже:

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

Ошибка Facebook:

 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 обратного вызова, передаваемый Facebook Stitch, будет иметь двойное кодирование. Кто-нибудь может сказать мне, что может вызвать это нежелательное поведение и как это исправить?

Комментарии:

1. Привет, Роберт, я также ответил на ваш вопрос на github, но у вас есть ссылка на ваше приложение Stitch, чтобы я мог просмотреть журналы здесь? Спасибо

Ответ №1:

Спасибо за подробное объяснение. Я попытался воспроизвести вашу проблему, но мне удалось успешно войти в Facebook.

Я также проверил URL, который сервер Stitch генерирует при перенаправлении на Facebook, и это был точно такой же URI с двойным кодированием, который у вас есть в вашем сообщении. Это означает, что такое поведение ожидаемо и не должно влиять на поток входа в систему.

Если вы посмотрите на полный URL, вы увидите, что основной URL (начинающийся с «https://www.facebook.com/login.php «) имеет параметр запроса с именем «next». Параметр «next» — это URL, поэтому он должен быть закодирован в URL. Этот URL, переданный в «next», имеет параметр «redirect_uri», который также является URL, поэтому он также должен быть закодирован в URL. Поскольку это URL-адрес в URL-адресе в URL-адресе, вот почему вы видите двойное кодирование.

Я отформатировал URL с каждым параметром в новой строке, и каждый дополнительный URL предназначен для демонстрации этого:

 https://www.facebook.com/login.php
    ?skip_api_login=1
    amp;api_key=<redacted>
    amp;kid_directed_site=0
    amp;app_id=<redacted>
    amp;signed_next=1
    amp;next=https://www.facebook.com/dialog/oauth
        ?access_type=offline
        &client_id%<redacted>

        // this is the double encoded URL
        &redirect_uri=https%3A%2F%2Fstitch.mongodb.com%2Fapi%2Fclient%2Fv2.0%2Fauth%2Fcallback

        &response_type=code
        &scope=email+public_profile
        &state=<redacted>
        &ret=login
        &fallback_redirect_uri%<redacted>
    amp;cancel_url=https://stitch.mongodb.com/api/client/v2.0/auth/callback
        ?error=access_denied
        &error_code=200
        &error_description=Permissions+error
        &error_reason=user_denied
        &state=<redacted>
    amp;display=pageamp;locale=en_US
  

Чтобы заставить Facebook войти в систему, я бы обеспечил следующее:

  • В консоли Facebook убедитесь, что этот URL добавлен в список «Допустимых URI перенаправления OAuth».:

  • В консоли Stitch убедитесь, что URL вашего приложения включен в список «Перенаправляющих URI» для Facebook Provider. Это должно включать любые завершающие косые черты.

  • В коде вашего приложения убедитесь, что вы вызываете следующий JS-код при попадании на ваш URL перенаправления. Это позволяет SDK клиента Stitch получать результат потока OAuth2, выполняемого сервером Stitch:

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

Проверьте https://docs.mongodb.com/stitch/authentication/facebook / для получения дополнительных пояснений по этим шагам.

Если у вас все еще возникают проблемы с запуском этой программы после описанных выше шагов, дайте мне знать, и я постараюсь помочь вам устранить проблему.