Remix 통합

Better Auth는 Remix와 쉽게 통합할 수 있습니다. 이 가이드는 Remix와 Better Auth를 통합하는 방법을 보여줍니다.

설치 가이드의 단계를 따라 시작하거나 이 가이드를 따라 Remix 방식으로 만들 수 있습니다.

설치 단계를 따랐다면 첫 번째 단계를 건너뛸 수 있습니다.

auth 인스턴스 생성

다음 위치 중 하나에 auth.server.ts라는 파일을 생성하세요:

  • 프로젝트 루트
  • lib/ 폴더
  • utils/ 폴더

이러한 폴더를 app/ 폴더 아래에 중첩할 수도 있습니다. (예: app/lib/auth.server.ts)

이 파일에서 Better Auth를 import하고 인스턴스를 생성하세요.

auth 인스턴스를 변수 이름 auth로 내보내거나 default export로 내보내야 합니다.

app/lib/auth.server.ts
import { betterAuth } from "better-auth"

export const auth = betterAuth({
    database: {
        provider: "postgres", // 데이터베이스 제공자로 변경하세요
        url: process.env.DATABASE_URL, // 데이터베이스 경로 또는 연결 문자열
    }
})

API 라우트 생성

핸들러를 API 라우트에 마운트해야 합니다. app/routes/ 디렉터리 내에 리소스 라우트 파일 api.auth.$.ts를 생성하세요. 그리고 다음 코드를 추가하세요:

app/routes/api.auth.$.ts
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)
}

Better Auth 설정에서 경로를 변경할 수 있지만 routes/api.auth.$.ts로 유지하는 것을 권장합니다

클라이언트 생성

클라이언트 인스턴스를 생성합니다. 여기서는 lib/ 디렉터리 내에 auth-client.ts 파일을 생성합니다.

app/lib/auth-client.ts
import { createAuthClient } from "better-auth/react" // better-auth/react에서 import해야 합니다

export const authClient = createAuthClient({
    // 클라이언트 설정을 여기에 전달할 수 있습니다
})

클라이언트를 생성한 후에는 회원가입, 로그인 및 기타 작업을 수행할 수 있습니다.

사용 예제

회원가입

app/routes/signup.tsx
import { Form } from "@remix-run/react"
import { useState } from "react"
import { authClient } from "~/lib/auth-client"

export default function SignUp() {
  const [email, setEmail] = useState("")
  const [name, setName] = useState("")
  const [password, setPassword] = useState("")

  const signUp = async () => {
    await authClient.signUp.email(
      {
        email,
        password,
        name,
      },
      {
        onRequest: (ctx) => {
          // 로딩 상태 표시
        },
        onSuccess: (ctx) => {
          // 홈으로 리디렉션
        },
        onError: (ctx) => {
          alert(ctx.error)
        },
      },
    )
  }

  return (
    <div>
      <h2>
        회원가입
      </h2>
      <Form
        onSubmit={signUp}
      >
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="이름"
        />
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="이메일"
        />
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          placeholder="비밀번호"
        />
        <button
          type="submit"
        >
          회원가입
        </button>
      </Form>
    </div>
  )
}

로그인

app/routes/signin.tsx
import { Form } from "@remix-run/react"
import { useState } from "react"
import { authClient } from "~/services/auth-client"

export default function SignIn() {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")

  const signIn = async () => {
    await authClient.signIn.email(
      {
        email,
        password,
      },
      {
        onRequest: (ctx) => {
          // 로딩 상태 표시
        },
        onSuccess: (ctx) => {
          // 홈으로 리디렉션
        },
        onError: (ctx) => {
          alert(ctx.error)
        },
      },
    )
  }

  return (
    <div>
      <h2>
        로그인
      </h2>
      <Form onSubmit={signIn}>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button
          type="submit"
        >
          로그인
        </button>
      </Form>
    </div>
  )
}

On this page