Header Banner
GG Logo

Future Engineering

기술의 최전선을 기록합니다.

기술 자료/Library/[Clerk] Middleware를 사용하여 Next.js에 인증 통합하기

[Clerk] Middleware를 사용하여 Next.js에 인증 통합하기

Library약 1년 전
※ Clerk 5버전입니다. 기존 4버전과 달라졌습니다.

 

Clerk Middleware 구성하기

프로젝트 루트 또는 src/ 디렉토리에 middleware.ts 파일을 생성하여 Clerk Middleware를 설정할 수 있습니다.

※ 아래 `middleware.ts` 는 모든 경로가 공개 경로로 적용됩니다.

// middleware.ts

import { clerkMiddleware } from '@clerk/nextjs/server';

export default clerkMiddleware();

export const config = {
  matcher: [
    // Next.js 내부 파일 및 모든 정적 파일을 제외, 검색 파라미터에서 발견되지 않은 경우
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // API 라우트 항상 실행
    '/(api|trpc)(.*)',
  ],
};

기본적으로, clerkMiddleware는 어떤 라우트도 보호하지 않습니다. 모든 라우트는 공개되어 있으며, 보호가 필요한 라우트는 수동으로 설정해야 합니다.

 

createRouteMatcher() 사용하기

createRouteMatcher()는 여러 라우트를 보호할 수 있는 Clerk 헬퍼 함수입니다. 이 함수는 배열 형태로 라우트를 받아 사용자가 접근하려는 라우트가 보호된 라우트인지 확인합니다.

※ 해당 내용을 가지고 경로를 보호할 수 있습니다. 전체 코드는 아래로!

const isProtectedRoute = createRouteMatcher([
  '/dashboard(.*)',
  '/forum(.*)',
]);

 

라우트 보호하기

사용자 인증 상태나 권한 상태를 기반으로 라우트를 보호할 수 있습니다. (전체 경로를 보호할 수 있고, 특정 경로만 보호할 수 있습니다. ) 

 

사용자 인증 상태 기반 보호

사용자가 로그인했는지 여부에 따라 라우트를 보호할 수 있습니다.

import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtectedRoute = createRouteMatcher([
  '/dashboard(.*)',
  '/forum(.*)',
]);

export default clerkMiddleware((auth, req) => {
  if (isProtectedRoute(req)) auth().protect();
});

export const config = {
  matcher: [
    // Next.js 내부 파일 및 모든 정적 파일을 제외
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // API 라우트 항상 실행
    '/(api|trpc)(.*)',
  ],
};

 

모든 라우트 보호하기

모든 라우트를 보호하고 특정 라우트를 공개하려면 조건문을 반대로 설정할 수 있습니다.


import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']);

export default clerkMiddleware((auth, request) => {
  if (!isPublicRoute(request)) {
    auth().protect();
  }
});

export const config = {
  matcher: [
    // Next.js 내부 파일 및 모든 정적 파일을 제외
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // API 라우트 항상 실행
    '/(api|trpc)(.*)',
  ],
};