인증 상태 지속성

Firebase JS SDK를 사용하면 인증 상태를 유지하는 방식을 지정할 수 있습니다. 로그인한 사용자가 명시적으로 로그아웃할 때까지 무기한 유지할지, 창을 닫으면 상태를 삭제할지, 아니면 페이지 새로고침 시 삭제할지 지정할 수 있습니다.

웹 애플리케이션의 경우 기본 동작은 사용자가 브라우저를 닫은 후에도 사용자의 세션을 유지하는 것입니다. 이 방식은 사용자가 동일한 기기에서 웹페이지를 방문할 때마다 매번 로그인하지 않아도 되므로 간편합니다. 다만 사용자가 비밀번호를 다시 입력하거나 SMS 인증을 전송하는 등의 과정이 필요할 수 있어 사용자 입장에서는 다소 복잡해질 수 있습니다.

하지만 다음과 같은 경우에는 이러한 동작이 적합하지 않을 수 있습니다.

  • 민감한 데이터가 있는 애플리케이션은 창이나 탭을 닫을 때마다 상태를 삭제하는 것이 좋습니다. 사용자가 로그아웃하는 것을 잊은 경우를 대비해서 필요합니다.
  • 여러 사용자가 공유하는 기기에서 사용되는 애플리케이션에는 적합하지 않습니다. 일반적인 예로는 도서관 컴퓨터에서 실행한 앱을 들 수 있습니다.
  • 여러 사용자가 액세스할 수 있는 공유 기기의 애플리케이션에도 적합하지 않습니다. 개발자가 이 애플리케이션의 액세스 방식을 알 수 없으며 사용자에게 세션 유지 여부를 선택할 수 있는 기능을 제공하고자 할 수도 있습니다. 로그인 과정에 '내 계정정보 저장' 옵션을 추가하면 이 기능을 제공할 수 있습니다.
  • 경우에 따라 사용자가 익명이 아닌 계정(제휴, 비밀번호, 전화번호 등)으로 업그레이드할 때까지 개발자가 익명 사용자를 유지하지 않으려고 할 수 있습니다.
  • 개발자가 여러 탭에서 서로 다른 사용자가 애플리케이션에 로그인할 수 있도록 허용하고자 할 수 있습니다. 기본 동작은 출처가 동일한 여러 탭에서 상태를 유지하는 것입니다.

위에 명시된 것처럼 기본 영구 지속성을 재정의해야 하는 여러 상황이 존재합니다.

지원되는 인증 상태 지속성 유형

애플리케이션 또는 사용자의 요구사항을 기준으로 지정된 Firebase 인증 인스턴스에 대해 3가지 인증 상태 지속성 유형 중 하나를 선택할 수 있습니다.

Enum 설명
firebase.auth.Auth.Persistence.LOCAL 'local' 브라우저 창이 닫히거나 React Native에서 활동이 폐기된 경우에도 상태가 유지됨을 나타냅니다. 이 상태를 삭제하려면 명시적으로 로그아웃해야 합니다. Firebase 인증 웹 세션은 단일 호스트 출처이며 단일 도메인의 경우에만 유지된다는 점에 유의하세요.
firebase.auth.Auth.Persistence.SESSION 'session' 현재의 세션이나 탭에서만 상태가 유지되며 사용자가 인증된 탭이나 창이 닫히면 삭제됨을 나타냅니다. 웹 앱에만 적용됩니다.
firebase.auth.Auth.Persistence.NONE 'none' 상태가 메모리에만 저장되며 창이나 활동이 새로고침되면 삭제됨을 나타냅니다.

인증 상태 지속성 수정

firebase.auth().setPersistence 메서드를 호출하면 기존의 지속성 유형을 지정하거나 수정할 수 있습니다.

웹 모듈식 API

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;
  });

웹 네임스페이스화된 API

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;
  });

이렇게 하면 현재 저장된 인증 세션에 지정한 인증 인스턴스에서 지속성 유형이 변경되고, 리디렉션 요청을 사용한 로그인을 포함해 이후 로그인 요청에 이러한 지속성 유형이 적용됩니다. 그러면 하나의 저장소 유형에서 다른 저장소 유형으로 상태 복사를 완료하고 나면 해결될 수 있는 프로미스가 반환됩니다. 지속성 유형을 변경한 후 로그인 메서드를 호출하면 변경이 완료될 때까지 대기한 후 새 인증 상태에 적용합니다.

웹브라우저와 React Native 앱의 기본값은 브라우저가 이 스토리지 메커니즘을 지원하는 경우(예: 서드 파티 쿠키 및 데이터가 사용 설정됨) local이며, Node.js 백엔드 앱의 기본값은 none입니다.

지속성 동작 개요

지속성의 현재 상태를 결정할 때 다음 기준이 적용됩니다.

  • 먼저 SDK에서 인증된 사용자가 있는지 확인합니다. setPersistence가 호출되지 않는 한 이 사용자의 현재 지속성 유형이 이후 로그인 시도에 적용됩니다. 따라서 사용자가 이전 웹페이지에서 session으로 유지되고 새 페이지를 방문한 경우 다른 사용자로 다시 로그인하면 이 사용자의 상태도 session 지속성으로 저장됩니다.
  • 로그인한 사용자가 없고 지속성이 지정되지 않은 경우 기본 설정(브라우저 앱의 경우 local)이 적용됩니다.
  • 로그인한 사용자가 없고 새로운 유형의 지속성이 설정된 경우 이후 로그인 시도 시 이 유형의 지속성을 사용합니다.
  • 사용자가 로그인한 상태에서 지속성 유형이 수정되면 기존 로그인 사용자의 지속성이 새 유형으로 변경됩니다. 이후 로그인 시도를 할 때마다 새로운 지속성 유형을 사용합니다.
  • signInWithRedirect가 호출되면 지속성이 none이었던 경우에도 현재 지속성 유형이 유지되고 새로 로그인한 사용자의 OAuth 흐름의 마지막 단계에 적용됩니다. 지속성이 이 페이지에 명시적으로 지정된 경우 리디렉션 과정이 시작된 이전 페이지에서 보유 인증 상태 지속성이 재정의됩니다.

    웹 모듈식 API

    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;
      });

    웹 네임스페이스화된 API

    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;
      });

브라우저 탭의 예상 동작

여러 탭에서 서로 다른 지속성 유형이 사용되면 다음 예상 동작이 적용됩니다. 어떠한 경우에도 동시에 여러 유형의 저장된 상태(예: 스토리지의 sessionlocal 유형으로 저장된 인증 상태)가 있어서는 안 됩니다.

  • 사용자는 여러 탭에서 다른 사용자로 session 또는 none 지속성을 사용해 로그인할 수 있습니다. 각 탭은 다른 탭의 상태를 확인할 수 없습니다.
  • local 지속성을 사용한 로그인 시도는 모든 탭에서 감지되고 동기화됩니다. 사용자가 이전에 session 또는 none 지속성을 사용해 특정 탭에서 로그인한 경우 이 상태가 삭제됩니다.
  • 사용자가 이전에 여러 탭이 열려 있는 상태에서 local 지속성을 사용해 로그인한 후 한 탭에서 none 또는 session 지속성으로 전환한 경우 이 탭의 상태가 session 또는 none으로 유지된 사용자로 수정되고 다른 모든 탭에서는 사용자가 로그아웃됩니다.