nextjs clerk 로그인 연동

nextjs 로그인 연동 하는 과정을 편하게 관리 할 수 있도록 하는 클라우드 서비스가 clerk라고 있더라고요. 무료로 사용 할 수 있으니까 https://dashboard.clerk.com 이동해서 가입하세요.

가격을 보면 5000명까지는 무료로 회원 관리 할 수 있어서 비용 걱정 없이 사용 할 수 있어요. 간단하게 구현하고 나서 나중에 바꾸면 될 것 같아요.

.env 파일을 사용 할 것이라서 .gitignore 파일에 .env 파일을 추가합니다.

대시보드 화면에서 Add application 눌러서 추가합니다. 추가하고 나면 키를 볼 수 있어요. 그 키를 복사해서 .env 에 내용을 넣습니다. 공식문서에 있는 변수를 .env 파일에 추가해놓습니다.

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=보안된키
CLERK_SECRET_KEY=또다른보안된키

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/

clerk 공식문서 https://clerk.com/docs/quickstarts/nextjs 보면서 따라해보면 좋습니다.

일단 설치합니다.

npm install @clerk/nextjs

공식문서 내용을 참고하여 layout.tsx 변경하는데 폴더를 별도로 생성합니다.

/app/(platform)/layout.tsx

import { ClerkProvider } from '@clerk/nextjs'


const PlatformLayout = ({
  children
}:{
  children: React.ReactNode
}) => {
  return (
    <ClerkProvider>
      {children}
    </ClerkProvider>  
  )
}

export default PlatformLayout;

로그인과 가입 화면 생성합니다.

/app/(platform)/(clerk)/sign-in/[[…sign-in]]/page.tsx 로그인 화면입니다.

import { SignIn } from "@clerk/nextjs";
 
export default function Page() {
  return <SignIn />;
}

/app/(platform)/(clerk)/sign-up/[[…sign-up]]/page.tsx 가입 화면입니다.

import { SignUp } from "@clerk/nextjs";
 
export default function Page() {
  return <SignUp />;
}

middleware.ts 파일을 최 상위에 만들어서 페이지에 따른 로그인 화면을 이동하게 보호합니다. 예제에는 publicRoutes 내용이 없지만 첫 페이지는 로그인 하지 않도록 접근 할 수 있도록 publicRoutes 설정합니다.

import { authMiddleware } from "@clerk/nextjs";
 
// This example protects all routes including api/trpc routes
// Please edit this to allow other routes to be public as needed.
// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middleware
export default authMiddleware({
  publicRoutes: ["/"]
});
 
export const config = {
  matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
};
 

그냥 만들고 나면 왼쪽 상단에 나오는데 가운데 나오도록 layout을 추가합니다.

/app/(platform)/(clerk)/layout.tsx

const ClerkLayout = ({
  children
} : { 
  children: React.ReactNode
}) => {
  return (
    <div className="h-full flex items-center justify-center">
      {children}
    </div>
  )
}

export default ClerkLayout;

작업은 끝났습니다. 이제 사용해봐요.

보호되는 화면을 만들어봐요.

아래 페이지는 로그인해야만 보이게 될 것입니다. 끝에 /protected로 로그인 가능해요.

/app/(platform)/protected/page.tsx

const Protectedpage = () => {
  return ( 
    <div>Please Login</div>
   );
}
 
export default Protectedpage;

로그인한 정보를 가져와 봅시다.

/app/(platform)/protected2/page.tsx

import { auth, currentUser } from "@clerk/nextjs";

const Protected2page = async () => {
  const user = await currentUser();
  const { userId } = auth();

  return ( 
    <div>
      Please Login
      User: {user?.firstName}
      userId: {userId}
    </div>
   );
}
 
export default Protected2page;

await 를 사용해야 해서 async 사용했는데요. 다른 방법으로 client 사이드에서 동작하도록 하는 함수가 별도로 있습니다.

/app/(platform)/protected3/page.tsx

'use client';

import { useAuth, useUser } from "@clerk/nextjs";

const Protected3page = () => {
  const { userId } = useAuth();
  const { user } = useUser();
  
  return ( 
    <div>
      Please Login
      User: {user?.firstName}
      userId: {userId}
    </div>
   );
}
 
export default Protected3page;

마지막으로 사용자 버튼이 나오도록 제공되는 함수를 사용해봐요. 사용자 버튼이 나오고 로그아웃 할 수 있습니다. afterSignOutUrl 파라미터를 이용해서 로그아웃 하고 나서 로그인 화면이 아니라 첫 화면이 나오도록 할 수 있어요.

/app/(platform)/protected4/page.tsx

'use client';

import { UserButton } from "@clerk/nextjs";

const Protected3page = () => {
  
  return ( 
    <UserButton 
      afterSignOutUrl="/"
    />
   );
}
 
export default Protected3page;

여기까지 clerk 서비스 이용해서 편하게 로그인 기능을 클라우드 이용해서 관리 해 봤습니다.

Leave a Comment