T3 스택에서 Clerk.io 설정하기: tRPC와의 통합 가이드
2024-10-07 08:11:41T3 스택이란?
T3 스택은 Next.js, TypeScript, Tailwind CSS, Prisma, tRPC를 포함하는 현대적인 웹 개발 스택입니다. 이러한 조합은 개발자들에게 빠르고 효율적인 개발 환경을 제공합니다. 각각의 요소가 어떻게 상호작용하는지 이해하는 것은 매우 중요합니다. 이번 블로그 포스트에서는 T3 스택에 Clerk.io를 통합하여 인증 및 사용자 관리 기능을 추가하는 방법에 대해 설명하겠습니다.
Clerk.io란?
Clerk.io는 인증, 사용자 관리 및 권한 부여를 간편하게 처리할 수 있도록 도와주는 서비스입니다. 특히, 프론트엔드 개발자들에게 매우 유용하며, 여러 종류의 OAuth 로그인을 지원합니다. 특히 Next.js와 잘 통합됩니다. 이번 가이드에서는 Clerk.io를 tRPC와 함께 사용하는 방법을 살펴보겠습니다.
Clerk.io 설치하기
Clerk.io를 설치하려면, 다음 명령어를 통해 패키지를 설치합니다:
npm install @clerk/nextjs
설치 후, Clerk.io의 API 키를 설정합니다. 이를 위해 Clerk Dashboard에서 API 키를 생성하고, 이를 환경 변수에 저장해야 합니다. .env.local 파일을 열고 다음과 같이 추가합니다:
CLERK_API_KEY=your_api_key_here
CLERK_FRONTEND_API=your_frontend_api_url
환경 변수를 설정한 후, Clerk를 초기화하기 위해 _app.tsx 파일을 수정해야 합니다.
_app.tsx 파일 수정
_app.tsx 파일에서 Clerk Provider를 추가하여 애플리케이션의 모든 페이지가 Clerk의 인증 상태를 접근할 수 있도록 합니다:
import { ClerkProvider, RedirectToSignIn } from '@clerk/nextjs';
import { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return (
<ClerkProvider>
<Component {...pageProps} />
</ClerkProvider>
);
}
export default MyApp;
이제 Clerk의 인증 기능이 애플리케이션에 통합되었습니다.
tRPC에 Clerk.io 통합하기
tRPC는 클라이언트와 서버 간의 타입 안전한 API 통신을 가능하게 합니다. Clerk과 tRPC를 함께 사용할 때, 인증 정보를 손쉽게 전달할 수 있습니다.
서버 컨텍스트 생성
먼저 server/context.ts 파일을 만들어 주어야 합니다. 다음과 같이 Clerk의 인증 정보를 tRPC 컨텍스트에 추가합니다:
import * as trpc from '@trpc/server';
import * as trpcNext from '@trpc/server/adapters/next';
import { getAuth } from '@clerk/nextjs/server';
export const createContext = async (opts: trpcNext.CreateNextContextOptions) => {
return {
auth: getAuth(opts.req),
};
};
export type Context = trpc.inferAsyncReturnType<typeof createContext>;
위 코드는 getAuth 함수로 인증 정보를 가져오고, 이를 tRPC 컨텍스트로 전달합니다. 이 부분이 페이지 라우터에서는 동작하지만, 앱 라우터에서는 다르게 작동합니다.
새로운 방식으로 tRPC 컨텍스트 정의하기
앱 라우터에서는 조금 다른 방법으로 구현해 주어야 합니다. 아래와 같은 코드를 server/trpc.ts 파일에 추가합니다:
import { currentUser } from "@clerk/nextjs";
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { ZodError } from "zod";
import { db } from "~/server/db";
export const createTRPCContext = async (opts: { headers: Headers }) => {
const user = await currentUser();
return {
db,
user,
...opts,
};
};
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.user?.id) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
user: ctx.user,
},
});
});
export const protectedProcedure = publicProcedure.use(isAuthed);
이 코드는 Clerk의 currentUser 함수를 사용하여 현재 사용자의 정보를 얻고, 이를 tRPC의 컨텍스트로 설정합니다. 또한, 사용자가 인증되지 않았다면 UNAUTHORIZED 에러를 발생시킵니다.
클라이언트에서 tRPC 사용하기
이제 인증된 사용자 정보가 뒷단에서 처리되었으니, 클라이언트 측에서 tRPC를 사용할 수 있습니다. 예를 들어, 인증된 사용자 정보를 가져오는 방법은 다음과 같습니다:
import { trpc } from "../utils/trpc";
const HomePage = () => {
const { data: userData } = trpc.user.getUser.useQuery();
return (
<div>
<h1>Hello, {userData?.name}</h1>
</div>
);
};
이 코드에서는 tRPC를 통해 서버에서 사용자 정보를 요청하고, 그 정보를 페이지에 출력합니다.
결론
이 포스트에서는 T3 스택에서 Clerk.io를 설정하고, tRPC와 함께 통합하는 방법에 대해 설명했습니다. 최신 API를 활용하여 앱 라우터와의 호환성 있는 방법으로 인증 시스템을 구축하는 것은 도전적이지만, 효과적으로 실행할 수 있습니다. Clerk.io에 대한 공식 문서가 자주 업데이트 되고 있으므로, 최신 정보를 참고하여 필요 시 구현 방식을 재조정하는 것이 좋습니다.
참고 자료
위의 자료들은 Clerk.io와 tRPC 통합에 대해 더 깊이 이해할 수 있는 도움이 될 것입니다. 위의 예제를 통해 여러분의 앱에도 인증 기능을 손쉽게 추가하시길 바랍니다.