Remix 集成

Better Auth 可以轻松集成到 Remix。本指南将向你展示如何将 Better Auth 与 Remix 集成。

🌐 Better Auth can be easily integrated with Remix. This guide will show you how to integrate Better Auth with Remix.

你可以按照 安装 中的步骤入门,或者你可以按照本指南以 Remix 的方式进行操作。

🌐 You can follow the steps from installation to get started or you can follow this guide to make it the Remix-way.

如果你已经按照安装步骤操作,可以跳过第一步。

🌐 If you have followed the installation steps, you can skip the first step.

创建认证实例

🌐 Create auth instance

在以下位置之一创建一个名为 auth.server.ts 的文件:

🌐 Create a file named auth.server.ts in one of these locations:

  • 项目根目录
  • lib/ 文件夹
  • utils/ 文件夹

你也可以将这些文件夹嵌套在 app/ 文件夹下。(例如 app/lib/auth.server.ts

🌐 You can also nest any of these folders under app/ folder. (e.g. app/lib/auth.server.ts)

在这个文件中,导入 Better Auth 并创建你的实例。

🌐 And in this file, import Better Auth and create your instance.

确保将身份验证实例以变量名 auth 导出,或者作为 default 导出。

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

export const auth = betterAuth({
    database: {
        provider: "postgres", //change this to your database provider
        url: process.env.DATABASE_URL, // path to your database or connection string
    }
})

创建 API 路由

🌐 Create API Route

我们需要将处理程序挂载到一个 API 路由上。在 app/routes/ 目录下创建一个资源路由文件 api.auth.$.ts。然后添加以下代码:

🌐 We need to mount the handler to a API route. Create a resource route file api.auth.$.ts inside app/routes/ directory. And add the following code:

app/routes/api.auth.$.ts
import { auth } from '~/lib/auth.server' // Adjust the path as necessary
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

创建客户端

🌐 Create a client

创建一个客户端实例。这里我们在 lib/ 目录下创建 auth-client.ts 文件。

🌐 Create a client instance. Here we are creating auth-client.ts file inside the lib/ directory.

app/lib/auth-client.ts
import { createAuthClient } from "better-auth/react" // make sure to import from better-auth/react

export const authClient = createAuthClient({
    //you can pass client configuration here
})

一旦创建了客户端,你就可以使用它进行注册、登录以及执行其他操作。

🌐 Once you have created the client, you can use it to sign up, sign in, and perform other actions.

示例用法

🌐 Example usage

注册

🌐 Sign Up

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) => {
          // show loading state
        },
        onSuccess: (ctx) => {
          // redirect to home
        },
        onError: (ctx) => {
          alert(ctx.error)
        },
      },
    )
  }

  return (
    <div>
      <h2>
        Sign Up
      </h2>
      <Form
        onSubmit={signUp}
      >
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="Name"
        />
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="Email"
        />
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          placeholder="Password"
        />
        <button
          type="submit"
        >
          Sign Up
        </button>
      </Form>
    </div>
  )
}

登录

🌐 Sign In

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) => {
          // show loading state
        },
        onSuccess: (ctx) => {
          // redirect to home
        },
        onError: (ctx) => {
          alert(ctx.error)
        },
      },
    )
  }

  return (
    <div>
      <h2>
        Sign In
      </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"
        >
          Sign In
        </button>
      </Form>
    </div>
  )
}

On this page