본문 바로가기

프로젝트 개발일지/플케어

[에러 해결] 로그인이 필요한 페이지 접근 시 로그인 모달창 띄우기

일단, 우리 사이트에서는 로그인 없이 접근할 수 있는 경우가 있고 로그인 없이 접근할 수 없는 경우가 있다.

그래서 이에 대한 추가적인 처리가 필요하다.

 

다음은 로그인 없이 접근할 수 있는 경우이다.

- 메인 페이지

- 프로젝트 인원 모집 페이지

- 프로젝트 인원 모집 특정 글

 

먼저, 로그인을 해야 접근할 수 있는 경우를 알아보자.

- 프로젝트 관리 페이지

- 프로젝트 인원 모집 글 작성 페이지

- 프로젝트 인원 모집 글에서 지원하기 버튼을 누르는 경우

- 프로젝트 인원 모집 글에서 좋아요 버튼을 누르는 경우

 

지금은 로그인 없이 모두 접근할 수 있도록 설정해 놨다.

하지만, 이제 로그인 여부에 따라 따로 처리해야 한다.

어떻게 처리해야 할지 먼저 생각해 봤다.

로그인을 해야 접근할 수 있는 경우가 한 가지가 아니라 여러 경우가 있었기 때문에, 특정 컴포넌트 내에서 하나하나 적기에는 너무 동일한 코드를 많이 적어야 하는 것 같았다.

 

그러다 GeneralLayout이라는 컴포넌트가 생각났다.

우리가 사용하는 모든 페이지에서 Header 컴포넌트가 필요했기 때문에 각 페이지마다 Header 컴포넌트를 따로 임포트해서 적어주지 않았다.

이때 GeneralLayout 컴포넌트를 사용해서 전체 레이아웃을 헤더를 포함하도록 설정했다.

 

해당 코드는 다음과 같다.

import { useEffect } from "react";
import {useSelector } from "react-redux";

import { getToken } from "../utils/localstroageHandler";
import { customAxios } from "../lib/apis/customAxios";

import MainHeader from "../components/common/MainHeader";

const GeneralLayout = ({ children }) => {
  const isLogin = useSelector((state) => state.auth.isLoggedIn);

  useEffect(() => {
    const accessToken = getToken("access_token");
    customAxios.defaults.headers.common[
      "Authorization"
    ] = `Bearer ${accessToken}`;
  }, [isLogin]);

  return (
    <>
      <MainHeader />
      <main>{children}</main>
    </>
  );
};

export default GeneralLayout;

 

여기에 로그인 관련 모달창을 제어할 수 있는 코드를 넣어보려 했다.

그리고 로그인 모달창 상태에 대한 state를 전역 상태로 관리해보도록 했다.

아래와 같이 전역 상태로 설정한 isLoginModalVisible이라는 state를 로그인이 필요한 페이지에 접근하거나 버튼을 누른 경우에 활성화해서 로그인 모달창이 띄워지도록 했다.

import { useEffect } from "react";
import { useSelector } from "react-redux";

import { getToken } from "../utils/localstroageHandler";
import { customAxios } from "../lib/apis/customAxios";

import Login from "../components/Login/Login";
import MainHeader from "../components/common/MainHeader";

const GeneralLayout = ({ children }) => {
  const isLogin = useSelector((state) => state.auth.isLoggedIn);
  const isLoginModalVisible = useSelector(
    (state) => state.auth.isLoginModalVisible
  );

  useEffect(() => {
    const accessToken = getToken("access_token");
    customAxios.defaults.headers.common[
      "Authorization"
    ] = `Bearer ${accessToken}`;
  }, [isLogin]);

  return (
    <>
      <MainHeader />
      <main>{children}</main>
      {isLoginModalVisible && <Login />}
    </>
  );
};

export default GeneralLayout;

 

다음 코드는 메인 헤더에서 링크 버튼을 클릭했을 때, 로그인이 필요 없는 모집글 페이지에 접속하려 했다면 모집글 페이지에 접속하게 했다.

그리고 만약 모집글이 아니라 로그인이 필요한 관리 페이지에 접근하려고 했다면 로그인 여부를 따져 로그인이 되어 있는 경우 관리 페이지에 접속시키고, 그게 아니라면 로그인 모달창을 띄우려고 했다.

const handleClickLinkMenu = useCallback((link) => {
    if (link === "/recruitment") {
      routeTo(link);
    } else if (!isToken("access_token")) {
      dispatch(authActions.setIsLoginModalVisible(true));
    } else {
      routeTo(link);
    }
  }, []);

 

로그인 없이 프로젝트 관리 탭에 들어가려고 했을 때 다음과 같이 로그인 모달창이 뜨게 된다.

 

로그인 모달창을 띄워야 하는 다른 컴포넌트들도 위와 같은 방식으로 코드를 작성했다.

 

로그인 모달창을 띄워야 하는 모든 경우에 동일한 코드를 작성하지 않고, GeneralLayout에만 해당 코드 작성 후 전역 상태로 관리하도록 했다.

앞으로 코드를 작성할 때, 공통으로 처리할 수 있는 코드들이 무엇인지 계속해서 고민해보고 중복된 코드를 작성하지 않으려 노력해야겠다.