최근에 아래 강의를 들으며 Clerk이라는 사용자 인증 솔루션을 알게되었다.
Next.js 15로 완성하는 실전 YouTube 클론 개발 강의 | antonio - 인프런
antonio | , [사진]클론코딩, 실전 개발을 익히는 최적의 학습법!클론코딩은 실제 서비스의 구조와 흐름을 몸으로 익히는 가장 빠른 방법이에요. 단순한 예제가 아닌, 우리가 잘 아는 실제 앱을 구
www.inflearn.com
이 솔루션을 사용하면 10분 안에 로그인 및 회원가입 기능을 구현할 수 있다.
실무에서 활용할 수 있을지 모르겠지만(돈이 드니까)
사이드프로젝트에서는 복잡한 로그인 및 회원가입 구현 없이 간편하게 소셜로그인을 적용할 수 있을 것 같아
Clerk을 사용하여 로그인 및 회원가입을 적용하는 방법을 정리해보려 한다.
우선 Clerk을 적용할 NextJS 프로젝트를 생성하였다.
그리고 아래 링크로 접속하여 인증 기능을 적용할 애플리케이션을 생성한다.
https://dashboard.clerk.com/apps/new
Sign in options에서 아이디로 사용할 값이나 소셜로그인 플랫폼을 선택할 수 있다.
애플리케이션 생성이 완료되면 Clerk 적용 과정을 설명하는 화면으로 이동하게 되는데 이 설명을 따라하면 된다.
우선 아래 명령어로 clerk 라이브러리를 설치한다.
npm install @clerk/nextjs
그리고 프로젝트 폴더 아래에 .env 파일을 생성한 후 공개키와 비밀키를 추가한다.
이 값은 애플리케이션 생성 후 이동하는 페이지에서 확인할 수 있다.
src 폴더 아래에 middleware.ts 파일을 생성한 후 아래 내용을 복붙한다.
import { clerkMiddleware } from '@clerk/nextjs/server';
export default clerkMiddleware();
export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
// Always run for API routes
'/(api|trpc)(.*)',
],
};
/src/app/layout.tsx로 이동한 후 RootLayout 컴포넌트의 html 요소를 ClerkProvider 컴포넌트로 감싼다.
import {ClerkProvider} from "@clerk/nextjs";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkProvider>
<html lang="en">
...
</html>
</ClerkProvider>
);
}
/app/(auth)/sign-in/[[...sign-in]]/page.tsx 파일을 생성하고 아래와 같이 로그인 화면을 생성한다.
import { SignIn } from '@clerk/nextjs'
export default function Page() {
return <SignIn />
}
/app/(auth)/sign-up/[[...sign-up]]/page.tsx 파일을 생성하고 아래와 같이 회원가입 화면을 생성한다.
import { SignUp } from '@clerk/nextjs'
export default function Page() {
return <SignUp />
}
/app/(auth)/layout.tsx파일을 생성하고 아래와 같이 레이아웃을 정의한다
import React from "react";
interface LayoutProps {
children : React.ReactNode;
}
const Layout = ({ children }: LayoutProps) => {
return (
<div className="min-h-screen flex items-center justify-center">
{children}
</div>
);
};
export default Layout;
앞서 생성한 파일구조는 다음과 같다.
.env 파일에 아래 코드를 추가한다.
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/
서버를 실행하고 /sign-in 경로와 /sign-up 경로로 접속하여
로그인 및 회원가입 페이지가 정상적으로 조회되는지 확인한다
일부 페이지를 로그인한 유저만 접근할 수 있도록 접근권한을 제한해보겠다.
접근권한 제한을 테스트하기 위해 /app/protected/page.tsx 파일을 생성한 후 간단한 페이지를 만들었다.
export default function ProtectedPage() {
return (
<div>
로그인한 유저한테만 보여야 함!
</div>
);
}
아직은 별도로 접근권한을 제한하지 않았기 때문에 로그인을 하지 않아도 접속이 가능한 것을 확인할 수 있다.
middleware.ts에 isProtectedRoute 함수를 생성하고 clerkMiddleware 함수를 수정한다.
만약 isProtectedRoute가 true를 반환하면 로그인 페이지로 이동된다.
import {clerkMiddleware, createRouteMatcher} from '@clerk/nextjs/server';
const isProtectedRoute = createRouteMatcher([
"/protected"
]);
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) await auth.protect();
});
현재 코드로는 /protected 경로만 접근이 제한되고 /protected/abc와 같은 하위 경로들의 접근은 제한되지 않는다.
만약 하위 경로도 접근을 제한하고 싶다면 제한 경로를 명시할 때 "/protected(.*)"와 같이 (.*)을 붙여야 한다.
다시 /protected로 접속하면 로그인 화면으로 리다이렉트 되는 것을 확인할 수 있다.
이제 사용자가 자발적으로 로그인할 수 있도록
로그인이 안된 상태에서 로그인 페이지로 이동하고,
로그인된 상태에서는 로그아웃되는 버튼 컴포넌트를 구현해보자.
/src/modules/auth/ui/components/auth-button.tsx 파일을 생성하고 아래 내용을 추가한다.
(컴포넌트의 위치는 마음대로 해도 상관 없다. )
"use client";
import {SignedIn, SignedOut, SignInButton, SignOutButton} from "@clerk/nextjs";
export const AuthButton = () => {
return (
<>
<SignedIn>
<SignOutButton>
<button>
Sign out
</button>
</SignOutButton>
</SignedIn>
<SignedOut>
<SignInButton>
<button>
Sign in
</button>
</SignInButton>
</SignedOut>
</>
);
};
기존 main 요소 안에 있던 코드들을 모두 삭제한 후 AuthButton 컴포넌트를 추가하였다.
<AuthButton/>
인덱스 페이지에 접속하면 로그인 버튼이 있는 것을 확인할 수 있다.
로그인을 하면 버튼의 라벨이 Sign out으로 바뀌고, /protected 경로에 접속할 수 있다.
SignInButton 컴포넌트의 mode 속성을 modal로 명시하면
버튼 클릭시 /sign-in 페이지로 이동하는 것이 아니라 로그인 모달이 뜬다.
<SignInButton mode="modal">
<button>
Sign in
</button>
</SignInButton>
이번 포스팅에서는 Clerk 솔루션을 사용하여 간단하게 사용자 인증을 적용하는 법에 대해 알아보았다.
로그인과 회원가입은 거의 모든 서비스에 필수적인 기능이지만 막상 구현하려면 참 귀찮다.
이런 귀찮음을 해결해 줄 수 있는 Clerk이라는 솔루션을 알게 되어서 좋았고,
앞으로 사이드 프로젝트를 할 때 적극적으로 활용해보고 싶다.
[ngrok] 무료로 내 로컬 웹서버 배포하기 | reverse proxy, local 터널링 (0) | 2025.06.12 |
---|---|
Neon으로 3초만에 무료 DB 서버 만들기 & NextJS에 연동 (0) | 2025.06.11 |
노션 API 연동 데모 코드 분석하기 | Express.js, Notion API (1) | 2025.05.28 |
Notion API 연동 데모 서버 실행해보기 | Notion Integration 생성/등록/연동 (1) | 2025.05.27 |
백업테이블에서 변경사항 추출하여 UPDATE문 생성하는 쿼리(feat. GPT4) (0) | 2025.03.28 |