NextAuth.js에서 Better Auth로 마이그레이션

이 가이드에서는 NextAuth.js에서 Better Auth로 프로젝트를 마이그레이션하는 단계를 안내하며, 데이터나 기능의 손실이 없도록 합니다. 이 가이드는 Next.js에 초점을 맞추고 있지만 다른 프레임워크에도 적용할 수 있습니다.


시작하기 전에

마이그레이션 프로세스를 시작하기 전에 프로젝트에서 Better Auth를 설정하세요. 설치 가이드를 따라 시작하세요.


기존 컬럼 매핑

기존 데이터베이스 컬럼 이름을 변경하는 대신 Better Auth의 예상 구조와 일치하도록 매핑할 수 있습니다. 이를 통해 현재 데이터베이스 스키마를 유지할 수 있습니다.

사용자 스키마

사용자 스키마에서 다음 필드를 매핑하세요:

  • (next-auth v4) emailVerified: datetime → boolean

세션 스키마

세션 스키마에서 다음 필드를 매핑하세요:

  • expiresexpiresAt
  • sessionTokentoken
  • (next-auth v4) datetime 타입의 createdAt 추가
  • (next-auth v4) datetime 타입의 updatedAt 추가
auth.ts
export const auth = betterAuth({
    // 기타 설정
    session: {
        fields: {
            expiresAt: "expires", // 기존 `expires` 필드를 Better Auth의 `expiresAt`에 매핑
            token: "sessionToken" // 기존 `sessionToken` 필드를 Better Auth의 `token`에 매핑
        }
    },
});

세션 스키마에 createdAtupdatedAt 필드가 있는지 확인하세요.

계정 스키마

계정 스키마에서 다음 필드를 매핑하세요:

  • (next-auth v4) providerproviderId
  • providerAccountIdaccountId
  • refresh_tokenrefreshToken
  • access_tokenaccessToken
  • (next-auth v3) access_token_expiresaccessTokenExpiresAt 및 int → datetime
  • (next-auth v4) expires_ataccessTokenExpiresAt 및 int → datetime
  • id_tokenidToken
  • (next-auth v4) datetime 타입의 createdAt 추가
  • (next-auth v4) datetime 타입의 updatedAt 추가

Better Auth에서는 필요하지 않으므로 session_state, type, token_type 필드를 제거하세요.

auth.ts
export const auth = betterAuth({
    // 기타 설정
    account: {
        fields: {
            accountId: "providerAccountId",
            refreshToken: "refresh_token",
            accessToken: "access_token",
            accessTokenExpiresAt: "access_token_expires",
            idToken: "id_token",
        }
    },
});

참고: ORM 어댑터를 사용하는 경우 스키마 파일에서 이러한 필드를 매핑할 수 있습니다.

Prisma를 사용한 예제:

schema.prisma
model Session {
    id          String   @id @default(cuid())
    expiresAt   DateTime @map("expires") // 기존 `expires` 필드를 Better Auth의 `expiresAt`에 매핑
    token       String   @map("sessionToken") // 기존 `sessionToken` 필드를 Better Auth의 `token`에 매핑
    userId      String
    user        User     @relation(fields: [userId], references: [id])
}

계정 스키마에 createdAtupdatedAt 필드가 있는지 확인하세요.

라우트 핸들러 업데이트

app/api/auth 폴더에서 [...nextauth] 파일의 이름을 [...all]로 변경하여 혼동을 피하세요. 그런 다음 route.ts 파일을 다음과 같이 업데이트하세요:

app/api/auth/[...all]/route.ts
import { toNextJsHandler } from "better-auth/next-js";
import { auth } from "~/server/auth";

export const { POST, GET } = toNextJsHandler(auth);

클라이언트 업데이트

lib 폴더에 auth-client.ts라는 파일을 만드세요. 다음 코드를 추가하세요:

auth-client.ts
import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
    baseURL: process.env.BASE_URL! // API 기본 URL이 프론트엔드와 일치하는 경우 선택 사항
});

export const { signIn, signOut, useSession } = authClient;

소셜 로그인 함수

Better Auth를 사용하도록 소셜 로그인 함수를 업데이트하세요. 예를 들어 Discord의 경우:

import { signIn } from "~/lib/auth-client";

export const signInDiscord = async () => {
    const data = await signIn.social({
        provider: "discord"
    });
    return data;
};

useSession 호출 업데이트

useSession 호출을 Better Auth 버전으로 교체하세요. 예제:

Profile.tsx
import { useSession } from "~/lib/auth-client";

export const Profile = () => {
    const { data } = useSession();
    return (
        <div>
            <pre>
                {JSON.stringify(data, null, 2)}
            </pre>
        </div>
    );
};

서버 측 세션 처리

auth 인스턴스를 사용하여 서버에서 세션 데이터를 가져오세요:

actions.ts
"use server";

import { auth } from "~/server/auth";
import { headers } from "next/headers";

export const protectedAction = async () => {
    const session = await auth.api.getSession({
        headers: await headers(),
    });
};

미들웨어

미들웨어로 라우트를 보호하려면 Next.js 미들웨어 가이드를 참조하세요.

마무리

축하합니다! NextAuth.js에서 Better Auth로 성공적으로 마이그레이션했습니다. 여러 인증 방법이 포함된 완전한 구현을 보려면 데모 리포지토리를 확인하세요.

Better Auth는 더 큰 유연성과 더 많은 기능을 제공합니다. 문서를 탐색하여 전체 잠재력을 활용하세요.

On this page