Clerk
Clerk는 한마디로 말해서 "사용자 인증 + 유저 관리 풀패키지" 서비스입니다.
- 이메일/비밀번호 로그인, 이메일 코드 로그인
- Google, GitHub 같은 소셜 로그인(OAuth)
- 세션 관리, 토큰 검증, 보안 처리
- 유저 프로필 관리, 비밀번호 변경, 2FA 등
- 이미 잘 디자인된 로그인/회원가입 UI 컴포넌트 제공
Next.js에 Clerk를 붙이면, 우리는 <SignInButton />, <SignUpButton />, <UserButton /> 같은 컴포넌트를 가져다가 쓰는 것만으로 기본적인 인증 화면을 다 구현할 수 있습니다.
백엔드에서 JWT, 세션, 쿠키를 직접 관리하지 않아도 되고, "로그인한 유저가 누구인지"에 대한 정보도 Clerk가 알아서 Next.js 서버/클라이언트에 넘겨줍니다.
@clerk/nextjs 설치하기
Clerk의 Next.js SDK 패키지를 설치합니다.
# npm
npm install @clerk/nextjs
# 또는 pnpm
pnpm add @clerk/nextjs
설치가 끝나면, Clerk 대시보드에서 발급받은 Publishable key / Secret key를 .env.local에 추가해야 합니다.
(대시보드에서 새 애플리케이션을 만들면 발급됩니다.)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
clerkMiddleware() 추가해서 인증 상태 연결하기
Clerk는 Next.js의 미들웨어에 자신들의 clerkMiddleware()를 연결해서, 각 요청에 대한
- 인증 정보(로그인 여부)
- 현재 유저 세션
등을 자동으로 붙여줍니다.
공식 Quickstart 기준으로는 Next.js 15에서는 proxy.ts, 그 이하 버전에서는 middleware.ts 파일 이름을 사용합니다.
proxy.ts 만들기
/src 디렉터리를 쓰고 있다면 src/proxy.ts, 루트에서 바로 App Router를 쓰고 있다면 proxy.ts를 프로젝트 루트에 생성합니다.
// proxy.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)(.*)',
],
};
- 지금 상태에서는 모든 페이지가 "공개" 상태입니다.
- 아직 특정 경로를 "로그인 필수"로 막지는 않았고, 단지 Clerk가 요청마다 인증 관련 정보를 붙일 수 있는 상태가 된 것입니다.
app/layout.tsx에 감싸기
이제 전체 앱의 루트 레이아웃에서 Clerk의 Context를 제공해야 합니다.
Next.js App Router에서는 app/layout.tsx가 모든 페이지를 감싸는 루트 컴포넌트 역할을 합니다.
ClerkProvider + 헤더 버튼 붙이기
app/layout.tsx를 아래와 같이 수정합니다.
// app/layout.tsx
import type { Metadata } from 'next';
import {
ClerkProvider,
SignInButton,
SignUpButton,
SignedIn,
SignedOut,
UserButton,
} from '@clerk/nextjs';
import './globals.css';
export const metadata: Metadata = {
title: 'Clerk Next.js Quickstart',
description: 'Clerk로 로그인/회원가입이 붙어 있는 Next.js 앱',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkProvider>
<html lang="ko">
<body className="min-h-screen bg-neutral-950 text-neutral-50">
{/* 헤더 영역: 오른쪽에 로그인/회원가입 or 유저 메뉴 */}
<header className="flex items-center justify-between px-4 sm:px-6 h-16 border-b border-neutral-800">
<div className="font-semibold">my-clerk-app</div>
{/* 로그인 안 돼 있을 때 */}
<SignedOut>
<div className="flex items-center gap-2 sm:gap-3">
<SignInButton>
<button className="px-3 py-1.5 text-sm rounded-full border border-neutral-600 hover:bg-neutral-900">
로그인
</button>
</SignInButton>
<SignUpButton>
<button className="px-4 py-1.5 text-sm rounded-full bg-violet-500 hover:bg-violet-400 text-white font-medium">
회원가입
</button>
</SignUpButton>
</div>
</SignedOut>
{/* 로그인 돼 있을 때 */}
<SignedIn>
{/* 아바타, 프로필, 로그아웃 메뉴를 포함한 드롭다운 */}
<UserButton afterSignOutUrl="/" />
</SignedIn>
</header>
<main className="max-w-3xl mx-auto w-full px-4 sm:px-6 py-6 sm:py-10">
{children}
</main>
</body>
</html>
</ClerkProvider>
);
}
- ClerkProvider로 전체 앱을 감싸서 Clerk Context를 전달합니다.
- SignedOut 영역 안에는 로그인하지 않은 유저에게만 보이는 UI를 넣습니다.
- 여기서는 <SignInButton />, <SignUpButton /> 두 개의 버튼을 넣었습니다.
- SignedIn 영역 안에는 로그인된 유저에게만 보이는 UI를 넣습니다.
- <UserButton /> 하나만 넣어도 프로필 팝오버, 로그아웃 메뉴까지 Clerk가 제공해 줍니다.
이 상태에서 앱을 실행하면, 헤더 오른쪽에 로그인이 자동으로 붙습니다.
Clerk를 사용하면 얻는 이점
지금까지 Clerk Quickstart를 기반으로, Next.js App Router에서 로그인/회원가입을 구현하는 전체 흐름을 살펴봤습니다.
정리해 보면 Clerk를 사용하면 다음과 같은 이점을 얻습니다.
- 구현 속도
- 버튼과 컴포넌트 몇 개로 로그인/회원가입, 유저 프로필까지 한 번에 붙일 수 있습니다.
- 보안 & 유지보수
- 비밀번호 저장, 세션 관리, 토큰 검증 등 민감한 부분을 Clerk가 대신 처리해 줍니다.
- 디자인 & UX
- 이미 잘 만들어진 UI 컴포넌트를 바로 사용할 수 있고, 필요하면 커스터마이징도 가능합니다.
- 확장성
- 나중에 소셜 로그인, 2FA, 온보딩 플로우 등 고급 기능을 추가해도 기본 구조는 그대로 가져갈 수 있습니다.
'개발 공부 > React' 카테고리의 다른 글
| Clerk PricingTable (0) | 2025.12.25 |
|---|---|
| 탭 간 상태 동기화 - React (0) | 2025.12.21 |
| UploadThing을 통한 이미지 업로드 구현하기 (0) | 2025.11.27 |
| Next.js App Router 자동 실행 규칙 (0) | 2025.11.24 |
| Next.js Route Handler (0) | 2025.11.22 |