설치
패키지 설치
먼저 프로젝트에 Better Auth를 추가해 보겠습니다:
npm install better-auth별도의 클라이언트와 서버 설정을 사용하는 경우 프로젝트의 양쪽 부분에 Better Auth를 설치해야 합니다.
환경 변수 설정
프로젝트 루트에 .env 파일을 생성하고 다음 환경 변수를 추가합니다:
- 비밀 키
라이브러리에서 암호화 및 해시 생성에 사용하는 무작위 값입니다. 아래 버튼을 사용하여 생성하거나 openssl과 같은 도구를 사용할 수 있습니다.
BETTER_AUTH_SECRET=- 기본 URL 설정
BETTER_AUTH_URL=http://localhost:3000 # 앱의 기본 URLBetter Auth 인스턴스 생성
다음 위치 중 하나에 auth.ts라는 파일을 생성합니다:
- 프로젝트 루트
lib/폴더utils/폴더
이러한 폴더를 src/, app/ 또는 server/ 폴더 아래에 중첩할 수도 있습니다. (예: src/lib/auth.ts, app/lib/auth.ts)
이 파일에서 Better Auth를 가져와 인증 인스턴스를 생성합니다. 변수 이름 auth로 내보내거나 default export로 내보내야 합니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...
});데이터베이스 구성
Better Auth는 사용자 데이터를 저장하기 위해 데이터베이스가 필요합니다. Better Auth를 SQLite, PostgreSQL, MySQL 등을 사용하도록 쉽게 구성할 수 있습니다!
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
})import { betterAuth } from "better-auth";
import { Pool } from "pg";
export const auth = betterAuth({
database: new Pool({
// 연결 옵션
}),
})import { betterAuth } from "better-auth";
import { createPool } from "mysql2/promise";
export const auth = betterAuth({
database: createPool({
// 연결 옵션
}),
})또는 ORM을 사용하려는 경우 내장된 어댑터 중 하나를 사용할 수 있습니다.
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/db"; // drizzle 인스턴스
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg", // 또는 "mysql", "sqlite"
}),
});import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
// Prisma 파일이 다른 곳에 있는 경우 경로를 변경할 수 있습니다
import { PrismaClient } from "@/generated/prisma";
const prisma = new PrismaClient();
export const auth = betterAuth({
database: prismaAdapter(prisma, {
provider: "sqlite", // 또는 "mysql", "postgresql", ...등
}),
});import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { client } from "@/db"; // mongodb 클라이언트
export const auth = betterAuth({
database: mongodbAdapter(client),
});데이터베이스가 위 목록에 없는 경우 지원되는 다른 데이터베이스를 확인하거나 지원되는 ORM 중 하나를 사용하세요.
데이터베이스 테이블 생성
Better Auth에는 라이브러리에서 필요한 스키마를 관리하는 데 도움이 되는 CLI 도구가 포함되어 있습니다.
- Generate: 이 명령은 ORM 스키마 또는 SQL 마이그레이션 파일을 생성합니다.
Kysely를 사용하는 경우 아래의 migrate 명령으로 마이그레이션을 직접 적용할 수 있습니다. 마이그레이션을 수동으로 적용할 계획인 경우에만 generate를 사용하세요.
npx @better-auth/cli generate- Migrate: 이 명령은 데이터베이스에 필요한 테이블을 직접 생성합니다. (내장된 Kysely 어댑터에서만 사용 가능)
npx @better-auth/cli migrate자세한 내용은 CLI 문서를 참조하세요.
대신 스키마를 수동으로 생성하려면 데이터베이스 섹션에서 필요한 핵심 스키마를 찾을 수 있습니다.
인증 방법
사용하려는 인증 방법을 구성합니다. Better Auth는 이메일/비밀번호 및 소셜 로그인 프로바이더에 대한 기본 지원을 제공합니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...다른 옵션
emailAndPassword: {
enabled: true,
},
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID as string,
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
},
},
});핸들러 마운트
API 요청을 처리하려면 서버에 라우트 핸들러를 설정해야 합니다.
프레임워크에서 지정한 catch-all 라우트 핸들러에 새 파일 또는 라우트를 생성합니다. 이 라우트는 /api/auth/* 경로에 대한 요청을 처리해야 합니다. (다른 기본 경로를 구성하지 않은 경우)
Better Auth는 표준 Request 및 Response 객체가 있는 모든 백엔드 프레임워크를 지원하며 인기 있는 프레임워크에 대한 헬퍼 함수를 제공합니다.
import { auth } from "@/lib/auth"; // 인증 파일 경로
import { toNextJsHandler } from "better-auth/next-js";
export const { POST, GET } = toNextJsHandler(auth);import { auth } from "~/utils/auth"; // 인증 파일 경로
export default defineEventHandler((event) => {
return auth.handler(toWebRequest(event));
});import { auth } from "$lib/auth"; // 인증 파일 경로
import { svelteKitHandler } from "better-auth/svelte-kit";
import { building } from '$app/environment'
export async function handle({ event, resolve }) {
return svelteKitHandler({ event, resolve, auth, building });
}import { auth } from '~/lib/auth.server' // 필요에 따라 경로 조정
import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node"
export async function loader({ request }: LoaderFunctionArgs) {
return auth.handler(request)
}
export async function action({ request }: ActionFunctionArgs) {
return auth.handler(request)
}import { auth } from "~/lib/auth"; // 인증 파일 경로
import { toSolidStartHandler } from "better-auth/solid-start";
export const { GET, POST } = toSolidStartHandler(auth);import { Hono } from "hono";
import { auth } from "./auth"; // 인증 파일 경로
import { serve } from "@hono/node-server";
import { cors } from "hono/cors";
const app = new Hono();
app.on(["POST", "GET"], "/api/auth/*", (c) => auth.handler(c.req.raw));
serve(app);import { auth } from "./auth"; // 인증 파일 경로
export default {
async fetch(request: Request) {
const url = new URL(request.url);
// 인증 라우트 처리
if (url.pathname.startsWith("/api/auth")) {
return auth.handler(request);
}
// 다른 라우트 처리
return new Response("Not found", { status: 404 });
},
};Node.js AsyncLocalStorage 지원: Better Auth는 비동기 컨텍스트 추적을 위해 AsyncLocalStorage를 사용합니다. Cloudflare Workers에서 이를 활성화하려면 wrangler.toml에 nodejs_compat 플래그를 추가하세요:
compatibility_flags = ["nodejs_compat"]
compatibility_date = "2024-09-23"또는 AsyncLocalStorage 지원만 필요한 경우:
compatibility_flags = ["nodejs_als"]다음 주요 릴리스에서는 AsyncLocalStorage 지원을 기본으로 가정하므로 이 구성이 필요합니다.
ExpressJS v5는 path-to-regexp@6으로 전환하여 라우트 경로 일치에 중대한 변경 사항을 도입했습니다. *와 같은 와일드카드 라우트는 이제 새로운 명명된 구문을 사용하여 작성해야 합니다. 예를 들어 /{*any}와 같이 catch-all 패턴을 올바르게 캡처해야 합니다. 이는 라우팅 시나리오 전반에서 호환성과 예측 가능한 동작을 보장합니다.
자세한 내용은 Express v5 마이그레이션 가이드를 참조하세요.
결과적으로 ExpressJS v5의 구현은 다음과 같아야 합니다:
app.all('/api/auth/{*any}', toNodeHandler(auth));이름 any는 임의적이며 원하는 식별자로 바꿀 수 있습니다.
import express from "express";
import { toNodeHandler } from "better-auth/node";
import { auth } from "./auth";
const app = express();
const port = 8000;
app.all("/api/auth/*", toNodeHandler(auth));
// Better Auth 핸들러 이후에 express json 미들웨어를 마운트하거나
// Better Auth와 상호 작용하지 않는 라우트에만 적용하세요
app.use(express.json());
app.listen(port, () => {
console.log(`Better Auth 앱이 포트 ${port}에서 실행 중입니다`);
});이것은 express, fastify, hapi 등과 같은 다른 노드 서버 프레임워크에서도 작동하지만 일부 수정이 필요할 수 있습니다. fastify 가이드를 참조하세요. CommonJS(cjs)는 지원되지 않습니다.
import type { APIRoute } from "astro";
import { auth } from "@/auth"; // 인증 파일 경로
export const GET: APIRoute = async (ctx) => {
return auth.handler(ctx.request);
};
export const POST: APIRoute = async (ctx) => {
return auth.handler(ctx.request);
};import { Elysia, Context } from "elysia";
import { auth } from "./auth";
const betterAuthView = (context: Context) => {
const BETTER_AUTH_ACCEPT_METHODS = ["POST", "GET"]
// 요청 메서드 검증
if(BETTER_AUTH_ACCEPT_METHODS.includes(context.request.method)) {
return auth.handler(context.request);
} else {
context.error(405)
}
}
const app = new Elysia().all("/api/auth/*", betterAuthView).listen(3000);
console.log(
`🦊 Elysia가 ${app.server?.hostname}:${app.server?.port}에서 실행 중입니다`
);import { auth } from '~/lib/server/auth'
import { createServerFileRoute } from '@tanstack/react-start/server'
export const ServerRoute = createServerFileRoute('/api/auth/$').methods({
GET: ({ request }) => {
return auth.handler(request)
},
POST: ({ request }) => {
return auth.handler(request)
},
});import { auth } from '@/lib/server/auth'; // 인증 파일 경로
const handler = auth.handler;
export { handler as GET, handler as POST };클라이언트 인스턴스 생성
클라이언트 측 라이브러리는 인증 서버와 상호 작용하는 데 도움이 됩니다. Better Auth는 바닐라 JavaScript를 포함한 모든 인기 있는 웹 프레임워크용 클라이언트를 제공합니다.
- 프레임워크에 맞는 패키지에서
createAuthClient를 가져옵니다. (예: React의 경우 "better-auth/react") - 함수를 호출하여 클라이언트를 생성합니다.
- 인증 서버의 기본 URL을 전달합니다. (인증 서버가 클라이언트와 동일한 도메인에서 실행 중인 경우 이 단계를 건너뛸 수 있습니다.)
/api/auth가 아닌 다른 기본 경로를 사용하는 경우 경로를 포함한 전체 URL을 전달해야 합니다. (예: http://localhost:3000/custom-path/auth)
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient({
/** 서버의 기본 URL (동일한 도메인을 사용하는 경우 선택사항) */
baseURL: "http://localhost:3000"
})import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
/** 서버의 기본 URL (동일한 도메인을 사용하는 경우 선택사항) */
baseURL: "http://localhost:3000"
})import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient({
/** 서버의 기본 URL (동일한 도메인을 사용하는 경우 선택사항) */
baseURL: "http://localhost:3000"
})import { createAuthClient } from "better-auth/svelte"
export const authClient = createAuthClient({
/** 서버의 기본 URL (동일한 도메인을 사용하는 경우 선택사항) */
baseURL: "http://localhost:3000"
})import { createAuthClient } from "better-auth/solid"
export const authClient = createAuthClient({
/** 서버의 기본 URL (동일한 도메인을 사용하는 경우 선택사항) */
baseURL: "http://localhost:3000"
})팁: 원하는 경우 특정 메서드를 내보낼 수도 있습니다:
export const { signIn, signUp, useSession } = createAuthClient()