본문 바로가기
Project/모익

로그인 여부에 따른 접근 제한 처리하기

by 이의찬 2024. 1. 29.

0.TL;DR

  • 로그인 여부에 따라 접근제한 처리를 해야했음
  • 우선 하단 Navbar에 검증 로직을 넣어 로그인 상태에 따라 리다이렉트 처리
  • 이후 쿠키에 담긴 Refresh Token의 여부를 확인하고 곧바로 리다이렉트 하도록 개선

1. Why?

프로젝트 <모익>을 진행하며, 로그인 여부에 따라 접근제한 처리를 할 필요가 있었다.

  • 로그인을 완료한 유저
    • 메인 페이지를 비롯한 다른 페이지 접근 가능, auth 관련 페이지 접근 불가능
  • 로그인을 하지 않은 유저
    • splash & auth 관련 페이지만 접근 가능, 나머지 페이지들 접근 불가능

2. How?

처음 떠올린 방법은 Layout에 검증 로직을 넣는 것이였다.

  • 장점
    • 모든 페이지에 손쉽게 접근 제한 처리를 할 수 있다.
    • 관리도 쉬워진다.
  • 단점
    • Layout에 useEffect로 로그인 여부를 체크하면 사용하면 모든 페이지가 클라이언트에서 동작할 것이다.

이 때, Figma로 화면 기획을 보다가 auth와 splash만 하단 Navbar가 없다는 사실을 깨달았다. Navbar에서 로그인 여부를 판별하는 방식은 어떨까?

 

모든 페이지에 검증 로직을 넣는 방식에 비해 관리도 편해지고, 모든 페이지가 CSR로 동작한다는 단점도 없어지기에 상대적으로 낫다고 생각해 이 방식으로 구현했다.

화면 기획

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export const useAlreadySignInChecker = () => {
  const router = useRouter();

  useEffect(() => {
    if (localStorage.getItem('access_token') !== null) {
      router.push('/home');
    }
  }, []);
};

export const useNotSignInChecker = () => {
  const router = useRouter();

  useEffect(() => {
    if (localStorage.getItem('access_token') === null) {
      router.push('/auth/signIn');
    }
  }, []);
};
  • useAlreadySignInChecker와 useNotSignInChecker라는 두 가지의 함수를 만들었다.
  • Navbar에는 useNotSignInChecker를, auth페이지들에는 useAlreadySignInChecker를 실행하도록 했다.

3. 개선하기

하지만 위의 방식은 여러 단점이 있는데

  1. 기획에 의존하는 방식이기에 추후에 로그인이 필요하지만 Navbar는 없는 페이지가 생긴다면?
  2. 화면 최하단의 Navbar가 랜더링 되는 시점에 리다이렉트되기에 화면이 사용자에게 노출됨

이런 점 때문에 개선 방안을 고민하다가 redirects를 통해 Next.js의 설정 파일에서 URL에 직접 접근하는 것을 막을 수 있다는 것을 알게되었다.

 

Token의 여부를 확인하고 Token이 있을 경우 원하는 경로로 리다이렉트 시킬 수 있는데, 이 경우 클라이언트단에서 Token 만료 여부를 알 수 없다는 문제점이 있었다. 하지만 리다이렉트 직후에 Token 만료 여부를 확인하는 로직을 거칠 것이기에 문제가 없다고 판단했다. 실제 구현 코드는 아래와 같다

module.exports = {
// 생략
  async redirects() {
    return [
      {
        source: '/auth/:path*',
        has: [
          {
            type: 'cookie',
            key: 'refreshToken',
            value: 'true',
          },
        ],
        permanent: true,
        destination: '/home',
      },
      {
        source: '/home',
        destination: '/auth/signIn',
        permanent: true,
        has: [
          {
            type: 'cookie',
            key: 'refreshToken',
            value: 'false',
          },
        ],
      },
      {
        source: '/map/:path*',
        destination: '/auth/signIn',
        permanent: true,
        has: [
          {
            type: 'cookie',
            key: 'refreshToken',
            value: 'false',
          },
        ],
      },
      {
        source: '/mypage/:path*',
        destination: '/auth/signIn',
        permanent: true,
        has: [
          {
            type: 'cookie',
            key: 'refreshToken',
            value: 'false',
          },
        ],
      },
      {
        source: '/profit/:path*',
        destination: '/auth/signIn',
        permanent: true,
        has: [
          {
            type: 'cookie',
            key: 'refreshToken',
            value: 'false',
          },
        ],
      },
    ];
  },
 }
  • Access token은 로컬 스토리지에, Refresh token은 쿠키에 담아서 서버와 주고받고 있는 상황
  • next.js의 redirects는 서버에서 이뤄지기에 클라이언트의 로컬 스토리지에 접근할 수 없다.
  • 그래서 Access token를 확인하는 대신 차선으로 Refresh token의 여부를 확인하고 리다이렉트가 이뤄지도록 했다.

  • 서버에서 경로를 확인하고 Refresh token이 없다면 곧바로 리다이렉트시키기에, 기존의 문제점을 해결할 수 있었다.
유저 인증 전체를 어떻게 처리했는지 궁금하다면 아래 글을 참조해주세요.
 

유저 인증 상태 관리하기 / 모익

1. Why? 프로젝트 에서 회원 관리 및 프론트엔드에서의 보안을 담당하게 되었는데, 그 과정에서 JWT와 OAuth를 사용해서 유저의 인증 상태를 관리했다. 이번 글에서는 어떻게 백엔드와 데이터를 주

cksxkr5193.tistory.com


4. 래퍼런스

 

https://nextjs.org/docs/app/api-reference/next-config-js/redirects

 

next.config.js Options: redirects | Next.js

Add redirects to your Next.js app.

nextjs.org

https://mingmeng030.tistory.com/272

 

[NextJs] next.config.js 의 redirects와 rewrites

nextJs에서 자동으로 생성되는 파일 중 next.config.js 가 있다. 이 파일에서는 redirects와 rewrites 를 작성할 수 있다. redirects React에서 Router 작성 시 사용했던 Navigate 태그와 유사하다고 생각된다. Source UR

mingmeng030.tistory.com