В этом документе описаны лучшие практики использования перенаправления при входе в систему в браузерах, блокирующих сторонние файлы cookie. Для корректной работы функции signInWithRedirect() в производственной среде и во всех браузерах необходимо следовать одному из перечисленных здесь вариантов.
Обзор
Для обеспечения бесперебойной работы функции signInWithRedirect() как для вас, так и для ваших пользователей, SDK Firebase Authentication JavaScript использует кросс-доменный iframe, который подключается к домену Firebase Hosting вашего приложения. Однако этот механизм не работает с браузерами, блокирующими доступ к сторонним хранилищам.
Поскольку просьба к пользователям отключить функцию разделения хранилища на разделы в браузере встречается крайне редко, вместо этого следует применить к вашему приложению один из следующих вариантов настройки, в зависимости от специфики вашего сценария использования.
- Если ваше приложение размещено на Firebase Hosting на поддомене
firebaseapp.com, эта проблема вас не затрагивает, и никаких действий не требуется. - Если вы размещаете свое приложение на Firebase Hosting на собственном домене или поддомене
web.app, используйте Вариант 1 . - Если вы размещаете свое приложение с помощью сервиса, отличного от Firebase, используйте Вариант 2 , Вариант 3 , Вариант 4 или Вариант 5 .
Вариант 1: Обновите конфигурацию Firebase, чтобы использовать свой собственный домен в качестве authDomain
Если вы размещаете свое приложение на Firebase Hosting с использованием собственного домена, вы можете настроить Firebase SDK для использования вашего собственного домена в качестве authDomain . Это гарантирует, что ваше приложение и iframe аутентификации будут использовать один и тот же домен, что предотвратит проблемы со входом в систему. (Если вы не используете Firebase Hosting, вам нужно использовать другой вариант.) Убедитесь, что вы настроили собственный домен в том же проекте, который используете для аутентификации.
Чтобы изменить конфигурацию Firebase и использовать свой собственный домен в качестве домена аутентификации, выполните следующие действия:
Настройте 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>" };
Добавьте новый
authDomainв список авторизованных URI перенаправления вашего OAuth-провайдера. Способ выполнения этого действия зависит от провайдера, но в целом вы можете следовать разделу «Прежде чем начать» в документации любого провайдера (например, провайдера Facebook ). Обновленный URI для авторизации выглядит следующим образомhttps://<the-domain-that-serves-your-app>/__/auth/handler— завершающий/__/auth/handlerважен.Аналогичным образом, если вы используете SAML-провайдер, добавьте новый
authDomainк URL-адресу службы обработки утверждений SAML (ACS).Убедитесь, что ваш
continue_uriнаходится в списке авторизованных доменов .При необходимости выполните повторное развертывание с использованием Firebase Hosting, чтобы получить самую актуальную версию файла конфигурации Firebase, размещенного по адресу
/__/firebase/init.json.
Вариант 2: Переключиться на signInWithPopup()
Используйте signInWithPopup() вместо signInWithRedirect() . Остальная часть кода вашего приложения останется неизменной, но объект UserCredential будет получен по-другому.
Web
// Before
// ==============
signInWithRedirect(auth, new GoogleAuthProvider());
// After the page redirects back
const userCred = await getRedirectResult(auth);
// After
// ==============
const userCred = await signInWithPopup(auth, new GoogleAuthProvider());
Web
// 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 ("authDomain содержит вспомогательный код для входа в систему, который перенаправляет на поставщика идентификации, который в случае успеха перенаправляет обратно на домен приложения.
Когда процесс аутентификации возвращается в домен вашего приложения, осуществляется доступ к хранилищу браузера домена вспомогательной функции входа в систему. Этот вариант, а также следующий (для самостоятельного размещения кода), исключают доступ к хранилищу из других источников, который в противном случае блокируется браузерами.
Настройте обратный прокси на сервере вашего приложения, чтобы 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; }Выполните действия, описанные в Варианте 1 , чтобы обновить authorized
redirect_uri, URL-адрес ACS и вашauthDomain. После повторного развертывания приложения доступ к хранилищу из разных источников должен прекратиться.
Вариант 4: Разместите вспомогательный код для авторизации на собственном домене.
Ещё один способ исключить доступ к хранилищу из разных источников — разместить вспомогательный код Firebase для входа в систему на собственном сервере. Однако этот подход не работает для входа через Apple или SAML. Используйте этот вариант только в том случае, если настройка обратного прокси, описанная в варианте 3, невозможна.
Размещение вспомогательного кода включает в себя следующие шаги:
Загрузите файлы для размещения на хостинге из папки
<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/__/auth/links wget https://<project>.firebaseapp.com/__/auth/links.js wget https://<project>.firebaseapp.com/__/firebase/init.jsonРазместите указанные выше файлы в домене вашего приложения. Убедитесь, что ваш веб-сервер может отвечать на запросы
https://<app domain>/__/auth/<filename>иhttps://<app domain>/__/firebase/init.json.Вот пример реализации сервера , который загружает и размещает файлы. Мы рекомендуем периодически загружать и синхронизировать файлы, чтобы обеспечить установку последних исправлений ошибок и новых функций.
Выполните действия, описанные в Варианте 1 , чтобы обновить authorized
redirect_uriи вашauthDomain. После повторного развертывания приложения доступ к хранилищу из разных источников должен прекратиться.
Вариант 5: Самостоятельная обработка входа в систему провайдера.
SDK аутентификации Firebase предоставляет методы signInWithPopup() и signInWithRedirect() в качестве удобных способов обертывания сложной логики и избежания необходимости использования другого SDK. Вы можете полностью избежать использования любого из этих методов, самостоятельно войдя в свою учетную запись у провайдера, а затем используя signInWithCredential() для обмена учетных данных провайдера на учетные данные Firebase Authentication. Например, вы можете использовать пример кода SDK входа в Google , чтобы получить учетные данные учетной записи Google, а затем создать новый экземпляр учетных данных Google, выполнив следующий код:
Web
// `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);
Web
// `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 находятся здесь .