기본 사용법
Better Auth는 다음과 같은 인증 방법을 기본적으로 지원합니다:
- 이메일과 비밀번호
- 소셜 프로바이더 (Google, GitHub, Apple 등)
또한 플러그인을 사용하여 쉽게 확장할 수 있습니다. 예를 들어 사용자명, 매직 링크, 패스키, 이메일 OTP 등이 있습니다.
이메일 & 비밀번호
이메일과 비밀번호 인증을 활성화하려면:
import { betterAuth } from "better-auth"
export const auth = betterAuth({
emailAndPassword: {
enabled: true
}
})회원가입
사용자를 가입시키려면 클라이언트 메서드 signUp.email을 사용자 정보와 함께 호출해야 합니다.
import { authClient } from "@/lib/auth-client"; //인증 클라이언트 가져오기
const { data, error } = await authClient.signUp.email({
email, // 사용자 이메일 주소
password, // 사용자 비밀번호 -> 기본적으로 최소 8자
name, // 사용자 표시 이름
image, // 사용자 이미지 URL (선택사항)
callbackURL: "/dashboard" // 사용자가 이메일을 인증한 후 리디렉션할 URL (선택사항)
}, {
onRequest: (ctx) => {
//로딩 표시
},
onSuccess: (ctx) => {
//대시보드 또는 로그인 페이지로 리디렉션
},
onError: (ctx) => {
// 오류 메시지 표시
alert(ctx.error.message);
},
});기본적으로 사용자는 회원가입에 성공하면 자동으로 로그인됩니다. 이 동작을 비활성화하려면 autoSignIn을 false로 설정할 수 있습니다.
import { betterAuth } from "better-auth"
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
autoSignIn: false //기본값은 true
},
})로그인
사용자를 로그인시키려면 클라이언트에서 제공하는 signIn.email 함수를 사용할 수 있습니다.
const { data, error } = await authClient.signIn.email({
/**
* 사용자 이메일
*/
email,
/**
* 사용자 비밀번호
*/
password,
/**
* 사용자가 이메일을 인증한 후 리디렉션할 URL (선택사항)
*/
callbackURL: "/dashboard",
/**
* 브라우저가 닫힌 후에도 사용자 세션을 기억합니다.
* @default true
*/
rememberMe: false
}, {
//콜백
})항상 클라이언트 측에서 클라이언트 메서드를 호출하세요. 서버에서 호출하지 마세요.
서버 측 인증
서버에서 사용자를 인증하려면 auth.api 메서드를 사용할 수 있습니다.
import { auth } from "./auth"; // Better Auth 서버 인스턴스 경로
const response = await auth.api.signInEmail({
body: {
email,
password
},
asResponse: true // 데이터 대신 응답 객체 반환
});서버가 응답 객체를 반환할 수 없는 경우, 쿠키를 수동으로 파싱하고 설정해야 합니다. 하지만 Next.js와 같은 프레임워크의 경우 이를 자동으로 처리하는 플러그인을 제공합니다.
소셜 로그인
Better Auth는 Google, GitHub, Apple, Discord 등 여러 소셜 프로바이더를 지원합니다. 소셜 프로바이더를 사용하려면 auth 객체의 socialProviders 옵션에서 필요한 프로바이더를 설정해야 합니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
}
},
})소셜 프로바이더로 로그인
소셜 프로바이더를 사용하여 로그인하려면 signIn.social을 호출해야 합니다. 다음 속성을 가진 객체를 받습니다:
import { authClient } from "@/lib/auth-client"; //인증 클라이언트 가져오기
await authClient.signIn.social({
/**
* 소셜 프로바이더 ID
* @example "github", "google", "apple"
*/
provider: "github",
/**
* 프로바이더로 사용자 인증 후 리디렉션할 URL
* @default "/"
*/
callbackURL: "/dashboard",
/**
* 로그인 과정에서 오류가 발생할 경우 리디렉션할 URL
*/
errorCallbackURL: "/error",
/**
* 사용자가 새로 가입한 경우 리디렉션할 URL
*/
newUserCallbackURL: "/welcome",
/**
* 프로바이더로의 자동 리디렉션을 비활성화합니다.
* @default false
*/
disableRedirect: true,
});사용자를 프로바이더 사이트로 리디렉션하는 대신 소셜 프로바이더의 idToken 또는 accessToken을 사용하여 인증할 수도 있습니다. 자세한 내용은 소셜 프로바이더 문서를 참조하세요.
로그아웃
사용자를 로그아웃시키려면 클라이언트에서 제공하는 signOut 함수를 사용할 수 있습니다.
await authClient.signOut();성공 시 리디렉션하려면 fetchOptions를 전달할 수 있습니다.
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
router.push("/login"); // 로그인 페이지로 리디렉션
},
},
});세션
사용자가 로그인하면 사용자 세션에 액세스하고 싶을 것입니다. Better Auth를 사용하면 서버와 클라이언트 측 모두에서 세션 데이터에 쉽게 액세스할 수 있습니다.
클라이언트 측
useSession 사용
Better Auth는 클라이언트 측에서 세션 데이터에 쉽게 액세스할 수 있는 useSession 훅을 제공합니다. 이 훅은 nanostore를 사용하여 구현되었으며 지원되는 각 프레임워크와 바닐라 클라이언트를 지원하므로 세션의 모든 변경 사항(예: 로그아웃)이 UI에 즉시 반영됩니다.
import { authClient } from "@/lib/auth-client" // 인증 클라이언트 가져오기
export function User(){
const {
data: session,
isPending, //로딩 상태
error, //오류 객체
refetch //세션 다시 가져오기
} = authClient.useSession()
return (
//...
)
}<script setup lang="ts">
import { authClient } from "~/lib/auth-client"
const session = authClient.useSession()
</script>
<template>
<div>
<div>
<pre>{{ session.data }}</pre>
<button v-if="session.data" @click="authClient.signOut()">
로그아웃
</button>
</div>
</div>
</template><script lang="ts">
import { authClient } from "$lib/auth-client";
const session = authClient.useSession();
</script>
<p>
{$session.data?.user.email}
</p>import { authClient } from "~/lib/auth-client"; //인증 클라이언트 가져오기
authClient.useSession.subscribe((value)=>{
//세션으로 무언가 수행 //
})import { authClient } from "~/lib/auth-client";
export default function Home() {
const session = authClient.useSession()
return (
<pre>{JSON.stringify(session(), null, 2)}</pre>
);
}getSession 사용
훅을 사용하지 않으려면 클라이언트에서 제공하는 getSession 메서드를 사용할 수 있습니다.
import { authClient } from "@/lib/auth-client" // 인증 클라이언트 가져오기
const { data: session, error } = await authClient.getSession()TanStack Query와 같은 클라이언트 측 데이터 페칭 라이브러리와 함께 사용할 수도 있습니다.
서버 측
서버는 세션 데이터에 액세스하는 데 사용할 수 있는 session 객체를 제공합니다. getSession 메서드에 요청 헤더 객체를 전달해야 합니다.
예제: 인기 있는 프레임워크 사용
import { auth } from "./auth"; // Better Auth 서버 인스턴스 경로
import { headers } from "next/headers";
const session = await auth.api.getSession({
headers: await headers() // 헤더 객체를 전달해야 합니다.
})import { auth } from "lib/auth"; // Better Auth 서버 인스턴스 경로
export async function loader({ request }: LoaderFunctionArgs) {
const session = await auth.api.getSession({
headers: request.headers
})
return json({ session })
}---
import { auth } from "./auth";
const session = await auth.api.getSession({
headers: Astro.request.headers,
});
---
<!-- Astro 템플릿 -->import { auth } from "./auth";
export async function load({ request }) {
const session = await auth.api.getSession({
headers: request.headers
})
return {
props: {
session
}
}
}import { auth } from "./auth";
const app = new Hono();
app.get("/path", async (c) => {
const session = await auth.api.getSession({
headers: c.req.raw.headers
})
});import { auth } from "~/utils/auth";
export default defineEventHandler((event) => {
const session = await auth.api.getSession({
headers: event.headers,
})
});import { auth } from "./auth";
import { createAPIFileRoute } from "@tanstack/start/api";
export const APIRoute = createAPIFileRoute("/api/$")({
GET: async ({ request }) => {
const session = await auth.api.getSession({
headers: request.headers
})
},
});자세한 내용은 세션 관리 문서를 확인하세요.
플러그인 사용
Better Auth의 고유한 기능 중 하나는 플러그인 생태계입니다. 이를 통해 적은 코드로 복잡한 인증 관련 기능을 추가할 수 있습니다.
다음은 2단계 인증 플러그인을 사용하여 2단계 인증을 추가하는 예제입니다.
서버 구성
플러그인을 추가하려면 플러그인을 가져와서 인증 인스턴스의 plugins 옵션에 전달해야 합니다. 예를 들어 2단계 인증을 추가하려면 다음 코드를 사용할 수 있습니다:
import { betterAuth } from "better-auth"
import { twoFactor } from "better-auth/plugins"
export const auth = betterAuth({
//...나머지 옵션
plugins: [
twoFactor()
]
})이제 2단계 인증 관련 라우트와 메서드가 서버에서 사용 가능합니다.
데이터베이스 마이그레이션
플러그인을 추가한 후 데이터베이스에 필요한 테이블을 추가해야 합니다. migrate 명령을 실행하거나 generate 명령을 사용하여 스키마를 생성하고 수동으로 마이그레이션을 처리할 수 있습니다.
스키마 생성:
npx @better-auth/cli generatemigrate 명령 사용:
npx @better-auth/cli migrate스키마를 수동으로 추가하려면 2단계 인증 플러그인 문서에서 필요한 스키마를 확인할 수 있습니다.
클라이언트 구성
서버 작업이 완료되면 클라이언트에 플러그인을 추가해야 합니다. 이를 위해 플러그인을 가져와서 인증 클라이언트의 plugins 옵션에 전달해야 합니다. 예를 들어 2단계 인증을 추가하려면 다음 코드를 사용할 수 있습니다:
import { createAuthClient } from "better-auth/client";
import { twoFactorClient } from "better-auth/client/plugins";
const authClient = createAuthClient({
plugins: [
twoFactorClient({
twoFactorPage: "/two-factor" // 사용자가 2단계 인증을 확인해야 할 때 리디렉션할 페이지
})
]
})이제 2단계 인증 관련 메서드가 클라이언트에서 사용 가능합니다.
import { authClient } from "./auth-client"
const enableTwoFactor = async() => {
const data = await authClient.twoFactor.enable({
password // 사용자 비밀번호가 필요합니다
}) // 2단계 인증을 활성화합니다
}
const disableTwoFactor = async() => {
const data = await authClient.twoFactor.disable({
password // 사용자 비밀번호가 필요합니다
}) // 2단계 인증을 비활성화합니다
}
const signInWith2Factor = async() => {
const data = await authClient.signIn.email({
//...
})
//사용자가 2단계 인증을 활성화한 경우 2단계 인증 페이지로 리디렉션됩니다
}
const verifyTOTP = async() => {
const data = await authClient.twoFactor.verifyTOTP({
code: "123456", // 사용자가 입력한 코드
/**
* 기기를 신뢰하는 경우 사용자는
* 동일한 기기에서 다시 2단계 인증을 통과할 필요가 없습니다
*/
trustDevice: true
})
}다음 단계: 2단계 인증 플러그인 문서를 참조하세요.