어제의 나보다 성장한 오늘의 나

[Next.js] getServerSideProps 에서 403 인증 에러 캐치 후 로그인 페이지로 리다이렉션 시키기 본문

Next.js

[Next.js] getServerSideProps 에서 403 인증 에러 캐치 후 로그인 페이지로 리다이렉션 시키기

today_me 2024. 1. 28. 17:04
반응형

 

 

 Next JS 프로젝트에서 인증 되지 않은 사용자가 페이지를 사용할 때는 로그인 페이지로 리다이렉션 시키는 로직을 추가하고자 했다.

 

 

 


 

 

플로우는 다음과 같다

 

getServerSideProps를 사용하여 서버 사이드에서 인증 토큰을 헤더에 넣어 GET 요청을 보낸다.
백앤드에서 토큰이 유효 하지 않음을 파악하고 403 에러를 반환한다.
403 에러를 캐치하여 페이지 렌더링 시 리다이렉션 시키는 로직을 추가한다.

 

 

 

 

getServerSideProps

// 서버 사이드 요청
const getServerSidePropsFunction: GetServerSideProps<{
  fetchData: IGetMileageCategory[];
}> = async (context) => {
  setServerSideCookie(context);        // 요청에 토큰 추가
  const res = await axiosInstance.get('/api/mileage/categories');
  const fetchData = res.data;

  return { props: { fetchData } };
};


// 에러 캐치 템플릿 적용
export const getServerSideProps = withTryCatchForSSR(getServerSidePropsFunction);


// requireLogin , error 전달
export default function MileageCategory({
  fetchData,
  requireLogin,
  error,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  if (requireLogin) {
    handleServerAuth403Error(error);
    return;
  }
  
  
  return (
   
   <>
   	...
   </>
  );
}

 

 

 

403TryCatchTemplate

import { GetServerSideProps } from 'next';
import axios, { AxiosError } from 'axios';

export const withTryCatchForSSR = <P>(
  getServerSidePropsFunction: GetServerSideProps<P>
): GetServerSideProps<P> => {
  return async (context) => {
    try {
      return await getServerSidePropsFunction(context);
    } catch (error) {
      const axiosError = error as AxiosError;

      if (axiosError.isAxiosError && axiosError.response?.status === 403) {
        return {
          props: {
            requireLogin: true,      // 로그인 필요함을 나타내는 플래그
            error: '로그인이 필요합니다',
            permanent: false,
          } as unknown as P,
        };
      } else {
        console.error('Error:', axiosError.message);
        return {
          props: {
            fetchData: null,
            error: axiosError.message || 'An error occurred',
          } as unknown as P,
        };
      }
    }
  };
};

 

 

 

handle403AuthError

// 쿠키 제거 및 로그인 페이지 리다이렉션
export const handleServerAuth403Error = async (errorMessage) => {
  setSession(null);   // 쿠키 제거
  window.location.href = '/auth/login';
  alert(errorMessage); 
};

 

반응형
Comments