Рекомендации по использованию SignInWithRedirect в браузерах, которые блокируют доступ к стороннему хранилищу

В этом документе описаны рекомендации по использованию входа в систему с перенаправлением в браузерах, которые блокируют сторонние файлы cookie. Вы должны следовать одному из перечисленных здесь параметров, чтобы функция signInWithRedirect() работала должным образом в производственных средах во всех браузерах.

Обзор

Чтобы сделать процесс signInWithRedirect() беспрепятственным для вас и ваших пользователей, Firebase Authentication JavaScript SDK использует iframe из разных источников, который подключается к домену хостинга Firebase вашего приложения. Однако этот механизм не работает с браузерами, которые блокируют доступ к стороннему хранилищу.

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

  • Если вы размещаете свое приложение с помощью хостинга Firebase на субдомене firebaseapp.com , эта проблема не затрагивает вас и никаких действий не требуется.
  • Если вы размещаете свое приложение с помощью хостинга Firebase в личном домене или поддомене web.app , используйте вариант 1 .
  • Если вы размещаете свое приложение с помощью службы, отличной от Firebase, используйте вариант 2 , вариант 3 , вариант 4 или вариант 5 .

Вариант 1. Обновите конфигурацию Firebase, чтобы использовать личный домен в качестве authDomain

Если вы размещаете свое приложение на хостинге Firebase с использованием личного домена, вы можете настроить Firebase SDK на использование вашего личного домена в качестве authDomain . Это гарантирует, что ваше приложение и iframe аутентификации используют один и тот же домен, что предотвращает проблемы со входом. (Если вы не используете хостинг Firebase, вам нужно использовать другой вариант.)

Чтобы обновить конфигурацию Firebase для использования вашего личного домена в качестве домена аутентификации, выполните следующие действия:

  1. Настройте Firebase JS SDK для использования вашего личного домена в качестве authDomain :

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
  2. Добавьте новый authDomain в список разрешенных URI перенаправления вашего поставщика OAuth. Как вы это сделаете, будет зависеть от провайдера, но в целом вы можете следовать разделу «Перед началом работы» любого провайдера для получения точных инструкций (например, провайдера Facebook ). Обновленный URI для авторизации выглядит так https://<the-domain-that-serves-your-app>/__/auth/handler — важен завершающий /__/auth/handler .

    Аналогичным образом, если вы используете поставщика SAML, добавьте новый authDomain в URL-адрес службы утверждений SAML (ACS).

  3. Убедитесь, что ваш continue_uri находится в списке авторизованных доменов .

  4. При необходимости выполните повторное развертывание с помощью хостинга Firebase, чтобы получить самую последнюю версию файла конфигурации Firebase, расположенного по адресу /__/firebase/init.json .

Вариант 2. Переключитесь на SignInWithPopup().

Используйте signInWithPopup() вместо signInWithRedirect() . Остальная часть кода вашего приложения остается прежней, но объект UserCredential извлекается по-другому.

Веб-модульный API

  // Before
  // ==============
  signInWithRedirect(auth, new GoogleAuthProvider());
  // After the page redirects back
  const userCred = await getRedirectResult(auth);

  // After
  // ==============
  const userCred = await signInWithPopup(auth, new GoogleAuthProvider());

Веб-API в пространстве имен

  // Before
  // ==============
  firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
  // After the page redirects back
  var userCred = await firebase.auth().getRedirectResult();

  // After
  // ==============
  var userCred = await firebase.auth().signInWithPopup(
      new firebase.auth.GoogleAuthProvider());
```

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

Вариант 3. Запросы аутентификации прокси-сервера на firebaseapp.com

Поток signInWithRedirect начинается с перенаправления из домена вашего приложения в домен, указанный в параметре authDomain в конфигурации Firebase (« .firebaseapp.com" по умолчанию). authDomain размещает вспомогательный код входа, который перенаправляет к поставщику удостоверений, который в случае успеха перенаправляет обратно в домен приложения.

Когда поток аутентификации возвращается в домен вашего приложения, открывается доступ к хранилищу браузера вспомогательного домена входа. Этот и следующий вариант (для самостоятельного размещения кода) исключают доступ к хранилищу из разных источников, который в противном случае блокируется браузерами.

  1. Настройте обратный прокси-сервер на своем сервере приложений, чтобы запросы GET/POST к https://<app domain>/__/auth/ перенаправлялись на https://<project>.firebaseapp.com/__/auth/ . Убедитесь, что эта переадресация прозрачна для браузера; это невозможно сделать с помощью перенаправления 302.

    Если вы используете nginx для обслуживания своего личного домена, конфигурация обратного прокси-сервера будет выглядеть следующим образом:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. Выполните действия, описанные в варианте 1 , чтобы обновить авторизованный redirect_uri , URL-адрес ACS и ваш authDomain . После повторного развертывания приложения доступ к хранилищу из разных источников больше не должен осуществляться.

Вариант 4. Разместите вспомогательный код входа в своем домене самостоятельно.

Еще один способ устранить доступ к хранилищу из разных источников — разместить вспомогательный код входа в Firebase самостоятельно. Однако этот подход не работает для входа в систему Apple или SAML. Используйте этот вариант только в том случае, если настройка обратного прокси-сервера в варианте 3 невозможна.

Размещение вспомогательного кода состоит из следующих шагов:

  1. Загрузите файлы на хост из местоположения <project>.firebaseapp.com , выполнив следующие команды:

    mkdir signin_helpers/ && cd signin_helpers
    wget https://<project>.firebaseapp.com/__/auth/handler
    wget https://<project>.firebaseapp.com/__/auth/handler.js
    wget https://<project>.firebaseapp.com/__/auth/experiments.js
    wget https://<project>.firebaseapp.com/__/auth/iframe
    wget https://<project>.firebaseapp.com/__/auth/iframe.js
    wget https://<project>.firebaseapp.com/__/firebase/init.json
    
  2. Разместите указанные выше файлы в домене своего приложения. Убедитесь, что ваш веб-сервер может ответить на https://<app domain>/__/auth/<filename> и https://<app domain>/__/firebase/init.json .

    Вот пример реализации сервера , который загружает и размещает файлы. Мы рекомендуем периодически загружать и синхронизировать файлы, чтобы получать последние исправления ошибок и новые функции.

  3. Выполните действия, описанные в варианте 1 , чтобы обновить авторизованный redirect_uri и ваш authDomain . После повторного развертывания приложения доступ к хранилищу из разных источников больше не должен осуществляться.

Вариант 5. Обработка входа в систему поставщика самостоятельно.

SDK Firebase Authentication предоставляет signInWithPopup() и signInWithRedirect() в качестве удобных методов для переноса сложной логики и устранения необходимости использования другого SDK. Вы можете полностью избежать использования любого метода, самостоятельно войдя в систему своего провайдера, а затем используя signInWithCredential() для обмена учетными данными провайдера на учетные данные аутентификации Firebase. Например, вы можете использовать Google Sign In SDK , пример кода , чтобы получить учетные данные учетной записи Google, а затем создать экземпляр новых учетных данных Google, выполнив следующий код:

Веб-модульный API

  // `googleUser` from the onsuccess Google Sign In callback.
  //  googUser = gapi.auth2.getAuthInstance().currentUser.get();
  const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
  const result = await signInWithCredential(auth, credential);

Веб-API в пространстве имен

  // `googleUser` from the onsuccess Google Sign In callback.
  const credential = firebase.auth.GoogleAuthProvider.credential(
      googleUser.getAuthResponse().id_token);
  const result = await firebase.auth().signInWithCredential(credential);

После того, как вы вызвали signInWithCredential() , остальная часть вашего приложения работает так же, как и раньше.

Инструкция по получению учетных данных Apple находится здесь .