상세 컨텐츠

본문 제목

Clerk으로 10분만에 로그인/회원가입 적용하기 | NextJS 15, 소셜로그인 구현

Development Study/잡기술

by yooputer 2025. 6. 10. 11:10

본문

 

최근에 아래 강의를 들으며 Clerk이라는 사용자 인증 솔루션을 알게되었다. 

 

Next.js 15로 완성하는 실전 YouTube 클론 개발 강의 | antonio - 인프런

antonio | , [사진]클론코딩, 실전 개발을 익히는 최적의 학습법!클론코딩은 실제 서비스의 구조와 흐름을 몸으로 익히는 가장 빠른 방법이에요. 단순한 예제가 아닌, 우리가 잘 아는 실제 앱을 구

www.inflearn.com

 

이 솔루션을 사용하면 10분 안에 로그인 및 회원가입 기능을 구현할 수 있다. 

실무에서 활용할 수 있을지 모르겠지만(돈이 드니까)

사이드프로젝트에서는 복잡한 로그인 및 회원가입 구현 없이 간편하게 소셜로그인을 적용할 수 있을 것 같아

Clerk을 사용하여 로그인 및 회원가입을 적용하는 방법을 정리해보려 한다. 


NextJS 프로젝트 생성

우선 Clerk을 적용할 NextJS 프로젝트를 생성하였다. 


Clerk 애플리케이션 생성

그리고 아래 링크로 접속하여 인증 기능을 적용할 애플리케이션을 생성한다. 

https://dashboard.clerk.com/apps/new

 

Sign in options에서 아이디로 사용할 값이나 소셜로그인 플랫폼을 선택할 수 있다. 

 

애플리케이션 생성이 완료되면 Clerk 적용 과정을 설명하는 화면으로 이동하게 되는데 이 설명을 따라하면 된다. 


Clerk 적용

clerk 라이브러리 설치

우선 아래 명령어로 clerk 라이브러리를 설치한다. 

npm install @clerk/nextjs

 

.env 작성

그리고 프로젝트 폴더 아래에 .env 파일을 생성한 후 공개키와 비밀키를 추가한다. 

이 값은 애플리케이션 생성 후 이동하는 페이지에서 확인할 수 있다. 

 

middleware.ts 추가

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)(.*)',
  ],
};

 

ClerkProvider 추가

/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 수정

.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 수정

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로 접속하면 로그인 화면으로 리다이렉트 되는 것을 확인할 수 있다. 


로그인/로그아웃 버튼 구현

이제 사용자가 자발적으로 로그인할 수 있도록

로그인이 안된 상태에서 로그인 페이지로 이동하고, 

로그인된 상태에서는 로그아웃되는 버튼 컴포넌트를 구현해보자. 

 

auth-button.tsx 작성

/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>
        </>
    );
};

 

/app/page.tsx 수정

기존 main 요소 안에 있던 코드들을 모두 삭제한 후 AuthButton 컴포넌트를 추가하였다. 

<AuthButton/>

 

테스트

인덱스 페이지에 접속하면 로그인 버튼이 있는 것을 확인할 수 있다. 

 

로그인을 하면 버튼의 라벨이 Sign out으로 바뀌고, /protected 경로에 접속할 수 있다. 


로그인 모달 띄우기

SignInButton 컴포넌트의 mode 속성을 modal로 명시하면

버튼 클릭시 /sign-in 페이지로 이동하는 것이 아니라 로그인 모달이 뜬다. 

<SignInButton mode="modal">
    <button>
        Sign in
    </button>
</SignInButton>

 


이번 포스팅에서는 Clerk 솔루션을 사용하여 간단하게 사용자 인증을 적용하는 법에 대해 알아보았다. 

로그인과 회원가입은 거의 모든 서비스에 필수적인 기능이지만 막상 구현하려면 참 귀찮다. 

이런 귀찮음을 해결해 줄 수 있는 Clerk이라는 솔루션을 알게 되어서 좋았고, 

앞으로 사이드 프로젝트를 할 때 적극적으로 활용해보고 싶다.

 

 

 

관련글 더보기