til

뉴스 피드 팀프로젝트 3일 차 @로그인/회원 가입 기능과 supabase auth, isLogin 페이지 접근 권한

fpzmfks 2024. 8. 30. 22:42

오늘도 또 새하얗게 불태우며 로그인 기능과 supabase auth, 로그인 상태에 따른 페이지 접근에 관해 코드를 짰다. 

 

supabase auth와 로그인 기능은 어제 오후부터 오늘 오전까지 계속해서 나를 골치아프게 했는데, 어찌저찌 해결은 되었다. 관련 기능을 이미 일부 구현하신 다른 조 팀원 분이 알려주셨는데, supabase의 로그인 기능과 supabase auth을 사용하기 위해서는 supabase authentication에 접근하여 user정보 테이블을 생성할 수 있어야 했다. 이 supabase authentication이야말로 로그인 기능 로직이 적용되는 부분이었던 것이다. 

 

다만 이 supabase authentication 내의 정보 중에서는 email, 암호화된 password, 고유 id만이 쓸만한 정보이기 때문에 이 테이블을 참조한 userinfo 테이블을 생성해야지만 username, profileimage 같은 사용자 정보들을 가질 수 있었다. 

 

또 이러한 데이터들을 contextAPI로 다루어서 로그인한 사용자 정보 저장하기, isLogin 상태값으로 페이지 접근 권한 설정하기 등의 과제들이 기다리고 있었다. 

 

빨간 마커를 보면 알 수 있듯이 전자의 contextAPI로 로그인한 사용자 정보 저장하기가 가장 힘들었다.

 

나는 로그인한 사용자 정보를 onAuthStateChange를 통해 signed_in 할 때 setState를 통해 상태값을 저장해달라고 했는데, 이 signed_in이라는 게 아무래도 내가 원하는 만큼 적게 발생하는 게 아닌듯 이렇게 저장한 사용자 정보는 undefined를 띄우고는 했다. 때문에 어쩔 수 없이 보다 정보는 적지만 undefined는 뜨지 않는 session을 사용자 정보에 저장을 해서 머지를 했었다. 이렇게 하면 고유id와 email 정도는 전달할 수 있지만 그 외에 필요한 사용자 정보를 불러오기 위해서 각 컴포넌트에서 다시 데이터를 불러올 필요가 생긴다. 

 

그리고 이 글을 작성하면서 정리한 내용을 바탕으로 onAuthStateChange가 아니라 로그인 페이지에서 사용하는 auth.signInWithPassword에서 로그인에 성공하면 일치하는 사용자 값을 로그인한 사용자 정보에 저장했다. 이렇게 저장한 값을 다른 컴포넌트에서 불러와보니 undefined가 안 뜨고 원하는 정보값이 전달되는 것을 확인할 수 있었다. 이전에도 이렇게 글을 작성하면서 그 날의 작업을 정리하다가 오류를 발견한 적이 있었는데, 이렇게 작업을 글로 정리하는 것이 확실히 코드의 이해에 크게 도움이 된다는 생각이 들었다. 

 

이외에 오늘은 간단하게 회원가입 기능도 구현해보았는데, 앞서 언급했듯이 supabase authentication의 user 테이블은 담을 수 있는 정보가 한정되어 있다. 때문에 당장에는 팀프로젝트 구성 회의 때 생각한대로 user_name과 profileImage의 초기값을 회원가입 과정에서 지정할 수가 없다. 일단 오늘로써 기본적인 기능은 모두 구현할 수 있었으니 남은 기간 동안 남은 과제를 모두 완료할 수 있으리라는 확신이 든다! 아마도! 최소한 회원가입에서는 안 되더라도 mypage에서 업데이트를 할 수는 있을 것이다. 

 


 

그리고 또 Router.jsx 파일에서 isLogin 값을 불러와서 로그인 여부에 따라 접근 가능한 페이지와 불가능한 페이지를 나누어보았다. 방법은 생각보다 간단했는데, 접근을 제한하고 싶은 Route들을 isLogin 값에 따라 홈이나 로그인페이지로 보내버리는 로직을 가진 상위 Route? 컴포넌트로 감싸는 것이다. 

 

이것이 접근을 제한하는 로직이고

const PrivateRoute = () => {
  const { isLogin } = useContext(dataContext);
  if (!isLogin) {
    alert("로그인을 해주세요");
    return <Navigate to="/sign#login" />;
  }
  return <Outlet />;
};

 

이것이 사용방법이다.

{/* 로그인 상태에서 접속 가능 */}
<Route element={<PrivateRoute />}>
    <Route path="/mypage" element={<Mypage />} />
    <Route path="/write" element={<PostWrite />} />
    <Route path="/modify/:id" element={<PostModify />} />
</Route>

 

이렇게 간단하게 적용은 끝났지만, 이러한 Router 접근제한 로직은 굉장히 빨리 실행되기 때문에 useNavigate훅 같은 것이 async await 같은 걸로 비동기 실행이라도 되었다가는 어어하다가 곧장 페이지에서 추방당하는 불편한 UX를 겪을 수 있었다. 또한 이렇게 페이지를 적용한 이후로는 접근제한이 있는 페이지에 주소창으로 경로를 지정하여 접근하려고 하면  로그인여부와 상관없이 추방당하게 되었다. 이러한 부분은 개선할 수 있으면 개선하는 게 좋을 것 같다.