행복을 담는 블로그

[TIL] zustand 새로고침 시 상태유지 reset ⇒ persist로 상태 유지 시키기 / role-based authentication 본문

TIL

[TIL] zustand 새로고침 시 상태유지 reset ⇒ persist로 상태 유지 시키기 / role-based authentication

hyun0zin 2024. 4. 12. 00:08

zustand에 isTeacher 값을 넣어서 상태를 유지 시켰는데, 새로고침 시 다시 제자리로 돌아옴…🥲

시도 1. zustand persist를 이용해서 isTeacher 값을 localStorage에 저장한다.

수강생↔강사 전환 버튼 시, isTeacher 값이 localStorage에서 바뀌는 것을 확인할 수 있다.

import { create } from 'zustand';
import { persist } from 'zustand/middleware';

interface UserRoleState {
  isTeacher: boolean | null;
  setIsTeacher: (value: boolean) => void;
}

export const useUserRoleStore = create(
  persist<UserRoleState>(
    (set) => ({
      isTeacher: false,
      setIsTeacher: (value: boolean) => {
        set({ isTeacher: value });
      }
    }),
    {
      name: 'userRoleStorage'
    }
  )
);

zustand의 persist 미들웨어를 이용해서 상태를 저장소(localStorage, SessionStorage 등)에 저장하여 데이터를 유지 시킬 수 있다.

🚨하지만 여기서 문제가..!

persist를 이용해서 localStorage에 상태를 저장했고, 해당 상태가 zustand에 그대로 남아있기 때문에, 로그아웃을 하고 새로 로그인을 하여도 그대로 상태가 유지된다.

하지만 문제가… 우리는 지금 하나의 id로 로그인 할 경우에는 해당 id에 맞는 상태가 저장되는데, 카카오 로그인을 했을 때 마지막 상태가 isTeacher : true인 선생님 상태로 로그아웃을 하더라도, 이후 구글 로그인으로 처음 사이트에 로그인을 하게 되면 isTeacher : false인 수강생으로 시작해야하는데, localStorage에 남아있는 isTeacher : true 값 때문에 처음 로그인한 회원도 선생님 상태가 되어버린다…!

즉,,, 로그인 한 유저의 id에 따라 zustand에 상태가 유지되어야 한다는 말..!

시도 2. 처음부터 로그인한 사람의 isTeacher 값을 db로 부터 받아와서 zustand에 저장하자

: role-based authentication으로 access control을 하는 방법 중 하나이다.

export default function useSetSessionStorage() {
  const { data: session } = useSession();

  useEffect(() => {
    if (!session) return;

    const userEmail = session?.user?.email ?? null;

    if (userEmail) {
      sessionStorage.setItem('userEmail', userEmail);
    }

    // supabase에서 isTeacher 값 불러오기
    const fetchUserRole = async () => {
      if (!userEmail) {
        console.error('이메일 값을 받아오지 못합니다.');
        return;
      }
      try {
        const userRole = await getUserRole(userEmail);
                const isTeacher = userRole?.isTeacher ?? false;

                //zustand에 상태 저장
        useUserRoleStore.setState({ isTeacher });
      } catch (error) {
        console.error('Failed to fetch user role', error);
      }
    };
    fetchUserRole();
  }, [session]);
  return;
}

로그인 시 저장되는 session에서 userEmail 값을 이용해서 유저를 구분해주는 것!

유저의 email이 있을 경우, getUserRole을 통해 users 테이블에서 isTeacher의 초기값(false)을 불러와서 useUserRoleStore 에 저장한다!

따라서 해당 값은 user의 email에 따라서 zustand에 다르게 저장되고, 이에 따라서 유저가 다른 아이디로 로그인 하더라도 해당 로그인한 유저의 isTeacher 값은 독립적으로 움직인다는 말!!

role이 다른 경우, zustand에 값을 저장해서 비교해나가자🔥