Сохранение состояния аутентификации

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

По умолчанию сеанс пользователя в веб-приложении сохраняется, даже если он закрыл браузер. Это удобно, поскольку пользователю не нужно каждый раз входить в аккаунт при посещении веб-страницы на одном и том же устройстве. Пользователю может потребоваться повторно ввести пароль, отправить SMS с кодом подтверждения и т. д., что может вызвать неудобства.

Однако в некоторых случаях такое поведение может быть нежелательным:

  • Приложения, работающие с конфиденциальными данными, могут очищать состояние при закрытии окна или вкладки. Это важно, если пользователь забудет выйти из аккаунта.
  • Приложения, которые используются на устройстве, к которому имеют доступ несколько пользователей. Распространенный пример – приложение, запущенное на компьютере в библиотеке.
  • Приложение на общем устройстве, к которому могут иметь доступ несколько пользователей. Разработчик не может определить, как пользователь получил доступ к приложению, и может захотеть предоставить ему возможность выбрать, сохранять сеанс или нет. Например, можно добавить вариант "Запомнить меня" на страницу входа.
  • В некоторых случаях разработчик может не сохранять данные анонимного пользователя, пока тот не перейдет на обычный аккаунт (федеративный, с паролем, номером телефона и т. д.).
  • Разработчик может захотеть разрешить разным пользователям входить в приложение на разных вкладках. По умолчанию состояние сохраняется на всех вкладках в пределах одного источника.

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

Поддерживаемые типы сохранения статуса авторизации

Вы можете выбрать один из трех типов сохранения состояния аутентификации в указанном экземпляре Firebase Auth в зависимости от требований приложения или пользователя.

Enum Значение Описание
firebase.auth.Auth.Persistence.LOCAL 'local' Указывает, что состояние будет сохраняться, даже если окно браузера закрыто или действие уничтожено в React Native. Чтобы сбросить этот статус, нужно выйти из аккаунта. Обратите внимание, что веб-сеансы Firebase Auth имеют источник с одним хостом и сохраняются только для одного домена.
firebase.auth.Auth.Persistence.SESSION 'session' Указывает, что состояние будет сохраняться только в текущем сеансе или вкладке и будет удалено, когда вкладка или окно, в котором пользователь прошел аутентификацию, будет закрыто. Применяется только к веб-приложениям.
firebase.auth.Auth.Persistence.NONE "none" Указывает, что состояние будет храниться только в памяти и будет очищено при обновлении окна или действия.

Как изменить сохранение состояния авторизации

Чтобы задать или изменить тип хранения, вызовите метод firebase.auth().setPersistence:

Web

import { getAuth, setPersistence, signInWithEmailAndPassword, browserSessionPersistence } from "firebase/auth";

const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
  .then(() => {
    // Existing and future Auth states are now persisted in the current
    // session only. Closing the window would clear any existing state even
    // if a user forgets to sign out.
    // ...
    // New sign-in will be persisted with session persistence.
    return signInWithEmailAndPassword(auth, email, password);
  })
  .catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
  });

Web

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
  .then(() => {
    // Existing and future Auth states are now persisted in the current
    // session only. Closing the window would clear any existing state even
    // if a user forgets to sign out.
    // ...
    // New sign-in will be persisted with session persistence.
    return firebase.auth().signInWithEmailAndPassword(email, password);
  })
  .catch((error) => {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
  });

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

По умолчанию для браузеров и приложений React Native используется значение local (если браузер поддерживает этот механизм хранения, например сторонние файлы cookie и данные включены), а для серверных приложений Node.js – none.

Общие сведения о сохранении данных

При определении текущего состояния сохранения будут применяться следующие критерии:

  • Сначала SDK проверит, существует ли аутентифицированный пользователь. Если не будет вызван метод setPersistence, для будущих попыток входа будет использоваться текущий тип сохранения данных пользователя. Если пользователь был сохранен в session на предыдущей странице и перешел на новую, повторный вход с другим аккаунтом приведет к тому, что состояние этого пользователя также будет сохранено с помощью session.
  • Если ни один пользователь не вошел в аккаунт и не указано, что нужно сохранить данные, будет применена настройка по умолчанию (local в приложении браузера).
  • Если ни один пользователь не вошел в аккаунт и задан новый тип сохранения данных, при любой попытке входа в будущем будет использоваться этот тип.
  • Если пользователь вошел в аккаунт и тип хранения данных изменен, для этого пользователя будет установлен новый тип хранения данных. Все последующие попытки входа будут использовать новые настройки.
  • Когда вызывается signInWithRedirect, текущий тип хранения сохраняется и применяется в конце потока OAuth к пользователю, который только что вошел в систему, даже если тип хранения был none. Если на этой странице явно указано, как долго должны храниться данные, то эти настройки переопределят настройки, заданные на предыдущей странице, с которой был начат процесс перенаправления.

    Web

    import { getAuth, setPersistence, signInWithRedirect, inMemoryPersistence, GoogleAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    setPersistence(auth, inMemoryPersistence)
      .then(() => {
        const provider = new GoogleAuthProvider();
        // In memory persistence will be applied to the signed in Google user
        // even though the persistence was set to 'none' and a page redirect
        // occurred.
        return signInWithRedirect(auth, provider);
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
      });

    Web

    firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE)
      .then(() => {
        var provider = new firebase.auth.GoogleAuthProvider();
        // In memory persistence will be applied to the signed in Google user
        // even though the persistence was set to 'none' and a page redirect
        // occurred.
        return firebase.auth().signInWithRedirect(provider);
      })
      .catch((error) => {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
      });

Ожидаемое поведение в разных вкладках браузера

Ниже описано, как будет работать браузер, если на разных вкладках используются разные типы сохранения данных. Требование заключается в том, что в любой момент времени не должно быть нескольких типов сохраненных состояний одновременно (например, состояние аутентификации, сохраненное в хранилищах типов session и local):

  • Пользователи могут входить в аккаунт с помощью постоянных файлов cookie session или none, используя разные аккаунты на нескольких вкладках. Каждая вкладка не может видеть состояние другой вкладки.
  • Любая попытка войти в аккаунт с использованием постоянного хранилища local будет обнаружена и синхронизирована на всех вкладках. Если пользователь ранее вошел в аккаунт на определенной вкладке с помощью постоянного хранилища session или none, этот статус будет сброшен.
  • Если пользователь ранее вошел в аккаунт с помощью постоянного хранения local и открыл несколько вкладок, а затем переключился на постоянное хранение none или session на одной из вкладок, состояние этой вкладки будет изменено: пользователь будет сохранен в session или none, а на всех остальных вкладках он выйдет из аккаунта.