본문 바로가기

Study/Side Projects

[Zeros] 로그인 상태 유지하기

localStorage.setItem

firebase를 통해 소셜 로그인을 구현하기는 했는데, 로그인 상태를 유지하는 로직을 어떻게 짜야 좋을지 고민이 많았다. 

 

페이지를 재방문했을 때에도 로그인 상태를 유지하도록 만드는 기능을 구현해 본 적이 있긴 하다. 이전에는 아래와 같은 방식으로 로그인 상태를 유지했다. 

 

 localStorage에 로그인 여부를 boolean으로 저장하고, 어플리케이션이 실행될 때 마다 이 값을 읽어온다. 값이 true일 때에는 login state를 true로 업데이트 한다. 

 

그러나 이 방법은 사용자가 로그인 상태를 조작하기 쉬워진다는 단점이 있다. 로컬 스토리지에 직접 값을 true로 입력해 두면, 실제로 로그인하지 않더라도 로그인 한 상태로 업데이트 되기 때문이다. 

firebase | setPersistence

로컬 boolean으로 값을 저장하는 것이 나쁘다는 것은 알겠는데, 그럼 어떻게 상태를 유지하면 좋을지 감이 안왔다. 그래서 초반에는 그냥 localStorage를 이용했다. 그러다가 우연히! 운 좋게도 firebase 공식 문서의 state persistence 챕터를 발견했다. 

 

export const firebaseLogin = async (providerName: ProviderName) => {
  let authProvider;

  switch (providerName) {
    case "Google":
      authProvider = new GoogleAuthProvider();
      break;
    case "Github":
      authProvider = new GithubAuthProvider();
      break;
    default:
      break;
  }

  await setPersistence(auth, browserLocalPersistence);
  await signInWithPopup(auth, authProvider as AuthProvider);
};

 

먼저 firebaseLogin 함수 에서 signInWithPopup을 호출하기 전, setPersistence를 호출해 주어야 한다. 

 

  useEffect(() => {
    auth //
      .onAuthStateChanged((user) => setUid(user?.uid || null));

    const now = new Date();
    const expiresIn = getExpiresinTime();
    if (!expiresIn) return;
    const remainingTime = calculateRemainigTime(expiresIn, now);

    if (isAfter(now, expiresIn)) {
      logout();
      return;
    }

    autoLogoutTimer = setTimeout(logout, remainingTime);
  }, [logout]);

 

그런 다음, AuthContext의 useEffect 내부에서 로그인 상태가 변할 때 마다 Uid를 업데이트 하는 함수를 호출한다. 여기서 state를 업데이트 해 주어야 로그인 상태에 따라 UI가 업데이트 되기 때문이다. 이제 isLoggedin의 값을 localStorage에서 받아오는 것이 아니라, !!auth.currentUser 등과 같은 값으로 대체할 수 있다.