본문 바로가기
내일배움캠프 TIL

2024-01-19 본 캠프 76일차 / 95일차 TIL (middleware 처리)

by KMS_99 2024. 1. 22.

2024-01-19 본 캠프 76일차 / 95일차 TIL (middleware 처리)

 

주요진행사항

- middleware 처리

 

 

middleware 처리

 

Next.js에서는 미들웨어라는 개념이 있다.

사용자의 요청(페이지 이동 및 정적 assets을 가져오는 요청)이 Next.js 서버에 도달하기 전에 실행되는 코드로 미들웨어를 통해서 사용자 요청 전 로그인 세션을 확인하거나 다른 페이지로 리다이렉트를 시키는 작업이 가능하다.

 

Next.js 12버전 이후에는 Edge Middleware 개념이 등장하였다.

 

Edge Middleware: Vercel의 EdgeNetwork에서 실행되어 더 빠른 응답시간을 제공한다.

Vercel의 EdgeNetwork란?
전세계에 분산된 서버 네트워크로, 분산되어있기 때문에 물리적 거리가 더 가까워지는 이점을 가지고 있다.
이러한 이점으로 더 빠른 콘텐츠 전송을 가능하게 한다.
따라서 Vercel의 EdgeNetwork을 이용하는 Edge Middleware는 물리적 거리에 이점이 생기면서 네트워크 지연시간이 크게 줄어들기 때문에 더 빠른 응답시간을 제공할 수 있다. 

 

이 Edge Middleware를 통해서 세션에 따른 조건부 페이지 이동과, 비 정상적인 접근시 홈으로 리다이렉트 시키는 로직을 구현하고 자한다.

 

next js의 pages router(14 version 이상)에서는 src 폴더에 _middleware.ts 파일을 통해 미들웨어 로직을 구현한다.

 

미들웨어의 로직 구성은 크게 2가지로 나누어진다

1. 미들웨어 로직

2. matcher 구성

 

1. 미들웨어 로직

미들웨어는 request를 통해 path 요청을 받으며, 해당 path의 정보를 얻을 수 있다.

쿠키를 통한 로그인 유무를 파악할 수 있었으며 해당 쿠키의 유/무를 통해 페이지 접근제어 로직을 구성하였다.

  // 로그인 세션에 따른 접근제한
  const sessionToken = request.cookies.get("pixtudy-access-token");
  const { pathname } = request.nextUrl;

  if (
    !sessionToken &&
    (pathname === "/dashboard" || pathname.startsWith("/metaverse"))
  ) {
    return NextResponse.redirect(new URL("/signin", request.url));
  }
  if (sessionToken && (pathname === "/signin" || pathname === "/signup")) {
    return NextResponse.redirect(new URL("/", request.url));
  }

  //   비정상적인 path에 접근 시 홈으로
  if (
    pathname !== "/" &&
    pathname !== "/dashboard" &&
    pathname !== "/signin" &&
    pathname !== "/signup" &&
    !pathname.startsWith("/metaverse")
  ) {
    return NextResponse.redirect(new URL("/", request.url));
  }

  return NextResponse.next();

 

 

2. matcher 구성

미들웨어에서 고려해야할 path를 골라내는 과정으로, 전체 주소를 모두 처리하는 것이 아니라 matcher를 통해 지정한 주소만 확인한다.

matcher는 정규식을 통해 구성이 가능하다.

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico|assets).*)"],
};

 

다음 코드는 정적인 asset과 페이지를 포함한다는 내용이다.

 

두 과정을 거친 전체 코드는 다음과 같다.

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  // 로그인 세션에 따른 접근제한
  const sessionToken = request.cookies.get("pixtudy-access-token");
  const { pathname } = request.nextUrl;

  if (
    !sessionToken &&
    (pathname === "/dashboard" || pathname.startsWith("/metaverse"))
  ) {
    return NextResponse.redirect(new URL("/signin", request.url));
  }
  if (sessionToken && (pathname === "/signin" || pathname === "/signup")) {
    return NextResponse.redirect(new URL("/", request.url));
  }

  //   비정상적인 path에 접근 시 홈으로
  if (
    pathname !== "/" &&
    pathname !== "/dashboard" &&
    pathname !== "/signin" &&
    pathname !== "/signup" &&
    !pathname.startsWith("/metaverse")
  ) {
    return NextResponse.redirect(new URL("/", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico|assets).*)"],
};