Client

Better Auth는 React, Vue, Svelte 등 인기 있는 프론트엔드 프레임워크와 호환되는 클라이언트 라이브러리를 제공합니다. 이 클라이언트 라이브러리에는 Better Auth 서버와 상호작용하기 위한 함수 세트가 포함되어 있습니다. 각 프레임워크의 클라이언트 라이브러리는 프레임워크에 구애받지 않는 코어 클라이언트 라이브러리 위에 구축되어 있어, 모든 메서드와 hook이 모든 클라이언트 라이브러리에서 일관되게 사용할 수 있습니다.

설치

아직 설치하지 않았다면 better-auth를 설치하세요.

npm i better-auth

클라이언트 인스턴스 생성

프레임워크에 맞는 패키지에서 createAuthClient를 가져옵니다 (예: React의 경우 "better-auth/react"). 함수를 호출하여 클라이언트를 생성합니다. 인증 서버의 기본 URL을 전달합니다. 인증 서버가 클라이언트와 같은 도메인에서 실행되는 경우 이 단계를 건너뛸 수 있습니다.

/api/auth 외의 다른 기본 경로를 사용하는 경우 경로를 포함한 전체 URL을 전달해야 합니다. (예: http://localhost:3000/custom-path/auth)

lib/auth-client.ts
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 인증 서버의 기본 URL
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 인증 서버의 기본 URL
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 인증 서버의 기본 URL
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/svelte"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 인증 서버의 기본 URL
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/solid"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 인증 서버의 기본 URL
})

사용법

클라이언트 인스턴스를 생성한 후 클라이언트를 사용하여 Better Auth 서버와 상호작용할 수 있습니다. 클라이언트는 기본적으로 함수 세트를 제공하며 플러그인으로 확장할 수 있습니다.

예시: 로그인

auth-client.ts
import { createAuthClient } from "better-auth/client"
const authClient = createAuthClient()

await authClient.signIn.email({
    email: "test@user.com",
    password: "password1234"
})

Hooks

표준 메서드 외에도 클라이언트는 다양한 반응형 데이터에 쉽게 액세스할 수 있는 hook을 제공합니다. 모든 hook은 클라이언트의 루트 객체에서 사용할 수 있으며 모두 use로 시작합니다.

예시: useSession

user.tsx
//React 클라이언트를 사용해야 합니다
import { createAuthClient } from "better-auth/react"
const { useSession } = createAuthClient() 

export function User() {
    const {
        data: session,
        isPending, //로딩 상태
        error, //에러 객체
        refetch //세션 다시 가져오기
    } = useSession()
    return (
        //...
    )
}
user.vue
<script lang="ts" setup>
import { authClient } from '@/lib/auth-client'
const session = authClient.useSession()
</script>
<template>
    <div>
        <button v-if="!session.data" @click="() => authClient.signIn.social({
            provider: 'github'
        })">
            GitHub로 계속하기
        </button>
        <div>
            <pre>{{ session.data }}</pre>
            <button v-if="session.data" @click="authClient.signOut()">
                로그아웃
            </button>
        </div>
    </div>
</template>
user.svelte
<script lang="ts">
import { client } from "$lib/client";
const session = client.useSession();
</script>

<div
    style="display: flex; flex-direction: column; gap: 10px; border-radius: 10px; border: 1px solid #4B453F; padding: 20px; margin-top: 10px;"
>
    <div>
    {#if $session.data}
        <div>
        <p>
            {$session.data.user.name}
        </p>
        <p>
            {$session.data.user.email}
        </p>
        <button
            onclick={async () => {
            await authClient.signOut();
            }}
        >
            로그아웃
        </button>
        </div>
    {:else}
        <button
        onclick={async () => {
            await authClient.signIn.social({
            provider: "github",
            });
        }}
        >
        GitHub로 계속하기
        </button>
    {/if}
    </div>
</div>
user.tsx
import { client } from "~/lib/client";
import { Show } from 'solid-js';

export default function Home() {
    const session = client.useSession()
    return (
        <Show
            when={session()}
            fallback={<button onClick={toggle}>로그인</button>}
        >
            <button onClick={toggle}>로그아웃</button>
        </Show>
    );
}

Fetch 옵션

클라이언트는 better fetch라는 라이브러리를 사용하여 서버에 요청을 보냅니다.

Better fetch는 네이티브 fetch API를 래핑하여 더 편리한 방식으로 요청할 수 있게 해주는 라이브러리입니다. Better Auth를 만든 같은 팀이 만들었으며 Better Auth와 원활하게 작동하도록 설계되었습니다.

createAuthClientfetchOptions 객체를 전달하여 클라이언트에 기본 fetch 옵션을 전달할 수 있습니다.

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

const authClient = createAuthClient({
    fetchOptions: {
        //모든 better-fetch 옵션
    },
})

대부분의 클라이언트 함수에 fetch 옵션을 전달할 수도 있습니다. 두 번째 인수로 전달하거나 객체의 속성으로 전달할 수 있습니다.

auth-client.ts
await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
}, {
    onSuccess(ctx) {
            //
    }
})

//또는

await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
    fetchOptions: {
        onSuccess(ctx) {
            //
        }
    },
})

에러 처리

대부분의 클라이언트 함수는 다음 속성을 가진 응답 객체를 반환합니다:

  • data: 응답 데이터
  • error: 에러가 발생한 경우 에러 객체

에러 객체는 다음 속성을 포함합니다:

  • message: 에러 메시지 (예: "잘못된 이메일 또는 비밀번호")
  • status: HTTP 상태 코드
  • statusText: HTTP 상태 텍스트
auth-client.ts
const { data, error } = await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234"
})
if (error) {
    //에러 처리
}

액션이 fetchOptions 옵션을 허용하는 경우 onError 콜백을 전달하여 에러를 처리할 수 있습니다.

auth-client.ts

await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
}, {
    onError(ctx) {
        //에러 처리
    }
})

//또는
await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
    fetchOptions: {
        onError(ctx) {
            //에러 처리
        }
    }
})

useSession과 같은 hook도 세션을 가져오는 중 에러가 발생한 경우 에러 객체를 반환합니다. 그 외에도 요청이 여전히 대기 중인지 나타내는 isPending 속성을 반환합니다.

auth-client.ts
const { data, error, isPending } = useSession()
if (error) {
    //에러 처리
}

에러 코드

클라이언트 인스턴스에는 서버에서 반환하는 모든 에러 코드를 포함하는 $ERROR_CODES 객체가 있습니다. 이를 사용하여 에러 번역이나 사용자 정의 에러 메시지를 처리할 수 있습니다.

auth-client.ts
const authClient = createAuthClient();

type ErrorTypes = Partial<
	Record<
		keyof typeof authClient.$ERROR_CODES,
		{
			en: string;
			es: string;
		}
	>
>;

const errorCodes = {
	USER_ALREADY_EXISTS: {
		en: "user already registered",
		es: "usuario ya registrada",
	},
} satisfies ErrorTypes;

const getErrorMessage = (code: string, lang: "en" | "es") => {
	if (code in errorCodes) {
		return errorCodes[code as keyof typeof errorCodes][lang];
	}
	return "";
};


const { error } = await authClient.signUp.email({
	email: "user@email.com",
	password: "password",
	name: "User",
});
if(error?.code){
    alert(getErrorMessage(error.code, "en"));
}

플러그인

플러그인으로 클라이언트를 확장하여 더 많은 기능을 추가할 수 있습니다. 플러그인은 클라이언트에 새 함수를 추가하거나 기존 함수를 수정할 수 있습니다.

예시: Magic Link 플러그인

auth-client.ts
import { createAuthClient } from "better-auth/client"
import { magicLinkClient } from "better-auth/client/plugins"

const authClient = createAuthClient({
    plugins: [
        magicLinkClient()
    ]
})

플러그인을 추가하면 플러그인이 제공하는 새 함수를 사용할 수 있습니다.

auth-client.ts
await authClient.signIn.magicLink({
    email: "test@email.com"
})

On this page