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 的文件:

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

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

  • Project root
  • lib/ folder
  • utils/ folder】

你也可以将这些文件夹嵌套在 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