В этом документе описаны рекомендации по использованию входа с переадресацией в браузерах, которые блокируют сторонние файлы cookie. Чтобы signInWithRedirect() работал в производственной среде во всех браузерах, необходимо выполнить одно из указанных ниже действий.
Обзор
Чтобы сделать процесс signInWithRedirect() удобным для вас и ваших пользователей, Firebase Authentication JavaScript SDK использует междоменный 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>" };
Добавьте новый URI перенаправления
authDomainв список авторизованных URI перенаправления поставщика OAuth. Инструкции зависят от поставщика, но в целом вы можете следовать указаниям из раздела "Перед началом работы" в любом руководстве по настройке поставщика (например, Facebook). Обновленный URI для авторизации выглядит так:https://<the-domain-that-serves-your-app>/__/auth/handler. Обратите внимание на символ/__/auth/handlerв конце.Если вы используете поставщика SAML, добавьте новый параметр
authDomainв URL сервиса Assertion Consumer Service (ACS) SAML.Убедитесь, что ваш
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, чтобы обновить авторизованный
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, чтобы обновить авторизованный файл
redirect_uriи файлauthDomain. После повторного развертывания приложения доступ к хранилищу с разных источников должен прекратиться.
Вариант 5. Обрабатывайте вход через поставщика услуг независимо
В Firebase Authentication SDK есть удобные методы signInWithPopup() и signInWithRedirect(), которые позволяют реализовать сложную логику без использования другого SDK. Вы можете вообще не использовать ни один из этих методов, если сначала самостоятельно войдете в аккаунт поставщика, а затем с помощью signInWithCredential() обменяете учетные данные поставщика на учетные данные Firebase Authentication.
Например, вы можете использовать Google Sign In SDK и пример кода, чтобы получить учетные данные аккаунта 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 приведены здесь.