본문 바로가기

트러블슈팅

Next.js에서 middleware 설정

문제상황

로그인을 한 사용자만 접속하게 하고 싶다.

해결과정

React에서는 Router나 각 페이지에서 로그인하지 않은 사용자는 접근할 수 없도록 설정해주었다면 Next.js에서는 rewrite를 사용해서 더 간편하게 설정해줄 수 있습니다.

 

미들웨어의 목적

이 미들웨어의 목적은 애플리케이션의 특정 부분에 대한 접근을 제어하는 것입니다. URL을 재작성하여 사용자를 다른 페이지로 라우팅함으로써, 검사를 수행하거나 다른 콘텐츠를 제공할 수 있습니다.

 

Next.js 애플리케이션의 미들웨어 함수 사용

middleware.tsx
import { NextResponse } from 'next/server' //요청을 수정하고 응답을 생성.
import type { NextRequest } from 'next/server' //들어오는 요청 객체의 타입을 정의.
 
export function middleware(request: NextRequest) {
  // 인증 토큰을 가져옵니다.
  const token = request.cookies.get('authToken');

  // 사용자가 로그인하지 않았을 경우 메인 페이지로 리디렉션합니다.
  if (!token) {
    return NextResponse.redirect(new URL('/', request.url));
  }

  // '/about' 경로에 대한 요청을 '/about-2'로 리라이트합니다.
  if (request.nextUrl.pathname.startsWith('/about')) {
    return NextResponse.rewrite(new URL('/about-2', request.url));
  }
 
  // '/dashboard' 경로에 대한 요청을 '/dashboard/user'로 리라이트합니다.
  if (request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.rewrite(new URL('/dashboard/user', request.url));
  }
}

 

 

 

  • 인증 확인
    • 사용자가 로그인했는지 확인하는 로직을 추가해야 합니다. 이는 쿠키, 헤더 또는 세션 데이터를 확인하여 수행할 수 있습니다.
  • 권한이 없는 접근 처리
    • 사용자가 인증되지 않은 경우 로그인 페이지나 권한 없음 페이지

 

이렇게 하면 사용자가 로그인하지 않았을 때 메인 페이지로 이동시키고, 특정 경로에 대한 URL 리라이트 기능도 유지할 수 있습니다.

 

미들웨어 사용으로 얻은 결과

1. 인증 및 접근 제어

  • 결과: 미들웨어를 사용하여 인증 토큰을 확인함으로써 로그인된 사용자만 특정 경로에 접근할 수 있도록 합니다. 로그인되지 않은 사용자는 자동으로 메인 페이지로 리디렉션됩니다.
  • 이점: 전역적으로 모든 요청을 검사할 수 있기 때문에, 페이지별로 개별적으로 인증 검사를 구현할 필요가 없어 코드의 중복을 줄일 수 있습니다. 또한 미들웨어는 모든 요청에 대해 일관된 접근 제어를 적용할 수 있습니다.

2. URL 리라이트

  • 결과: 특정 경로를 다른 경로로 재작성합니다. 예를 들어, /about 요청을 /about-2로, /dashboard 요청을 /dashboard/user로 리라이트합니다.
  • 이점: URL 구조를 변경하거나 특정 경로에 대한 트래픽을 다른 경로로 쉽게 재배치할 수 있습니다. 이는 SEO, 사용자 경험, 사이트 리팩토링 등에 유용합니다.

미들웨어를 사용하지 않았다면?

1. 각 페이지에서 인증 검사

  • 방법: 각 페이지 컴포넌트에서 인증 검사를 직접 수행하고, 로그인되지 않은 사용자를 메인 페이지로 리디렉션합니다.
  • 코드
import { useEffect } from 'react';
import { useRouter } from 'next/router';

const DashboardPage = () => {
  const router = useRouter();

  useEffect(() => {
    const token = getCookie('authToken'); // 쿠키에서 토큰 가져오기

    if (!token) {
      router.push('/'); // 메인 페이지로 리디렉션
    }
  }, []);

  return (
    <div>
      Dashboard Content
    </div>
  );
}

export default DashboardPage;
  • 단점
    • 중복 코드: 각 페이지마다 인증 검사를 추가해야 하므로 중복 코드가 발생합니다.
    • 일관성 부족: 모든 페이지에서 동일한 인증 로직을 유지하기 어려울 수 있습니다.
    • 유지보수 어려움: 인증 로직이 변경될 경우 모든 페이지를 수정해야 합니다.

결론

미들웨어를 사용하면 전역적으로 일관된 인증 및 URL 리라이트 로직을 구현할 수 있어 유지보수성이 높아지고 코드 중복을 줄일 수 있습니다. 반면, 미들웨어를 사용하지 않는다면 각 페이지마다 별도로 인증 로직을 구현해야 하므로 프로젝트가 커질수록 코드 중복과 관리의 어려움이 발생합니다. 미들웨어는 특히 인증과 같은 공통 로직을 처리하는 데 유리합니다.

 

 


 

공식문서 참고

https://nextjs.org/docs/app/building-your-application/routing/middleware