使用 Better Auth 在 Next.js 中快速集成登录注册功能

登录注册功能看似简单,但实际开发中涉及密码加密、Session 管理、OAuth 回调、CSRF 防护等大量细节,处理不当很容易造成数据泄露。几乎每个项目都需要这些功能,频繁造轮子意义不大。

Better Auth 是一款 TypeScript 优先的身份认证库,可以帮助你在项目中快速集成登录注册功能。与 Clerk、Supabase Auth 等方案不同,Better Auth 完全免费 ,且数据完全保存在你自己的数据库中,没有供应商锁定。它支持任意框架(Next.js、Remix、Svelte 等),支持 PostgreSQL、MySQL、SQLite 等多种数据库,内置了 OAuth、2FA、密码重置、Magic Link 等开箱即用的功能。

本文以 Next.js(App Router)为例,带你完整实现一套邮箱密码登录注册 + GitHub 第三方登录的系统。

一、创建 Next.js 项目

在终端中执行以下命令创建项目:

bash

复制代码
npx create-next-app@latest better-auth-demo

按提示选择配置:TypeScript、ESLint、Tailwind CSS、src/ 目录、App Router 均选 Yes。项目创建完成后,进入目录并安装 Better Auth:

bash

复制代码
npm install better-auth

二、配置数据库

Better Auth 支持 SQLite、PostgreSQL、MySQL 等多种数据库。这里使用 Neon 提供的免费 PostgreSQL 云数据库。

  1. 访问 neon.tech,使用 GitHub 账号登录

  2. 点击右上角创建新数据库(如 better-auth-demo),Region 选择新加坡(离国内较近,访问更快)

  3. 创建完成后,点击 Connect ,获取数据库连接字符串(postgresql://...

在项目根目录创建 .env 文件,写入以下环境变量:

env

复制代码
# 使用 openssl rand -base64 32 生成[reference:11]
BETTER_AUTH_SECRET=你的密钥
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=你的Neon数据库连接字符串

三、创建 Better Auth 实例

src/lib/ 目录下创建 auth.ts 文件:

ts

复制代码
import { betterAuth } from "better-auth";
import { pgAdapter } from "better-auth/adapters/postgres";

export const auth = betterAuth({
  database: pgAdapter(process.env.DATABASE_URL!),
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    },
  },
});

这里配置了邮箱密码登录和 GitHub OAuth 登录两种方式。

执行以下命令生成数据库表结构:

bash

复制代码
npx @better-auth/cli@latest generate

将生成的 SQL 语句在 Neon 的 SQL Editor 中执行,创建 Better Auth 所需的用户、会话等数据表。

四、创建 API 路由

src/app/api/auth/[...all]/route.ts 创建全量 API 路由,处理所有 /api/auth/* 的认证请求:

ts

复制代码
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

export const { POST, GET } = toNextJsHandler(auth);

五、创建前端 Client 实例

src/lib/ 下创建 auth-client.ts

ts

复制代码
import { createAuthClient } from "better-auth/client";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_BASE_URL!,
});

authClient 提供了 signInsignUpsignOutuseSession 等开箱即用的方法,前端可以直接调用,无需手动封装请求。

六、构建登录注册 UI

使用 shadcn/ui 快速搭建登录注册页面(需先安装 shadcn/ui)。

登录页面src/app/sign-in/page.tsx):

tsx

复制代码
"use client";

import { authClient } from "@/lib/auth-client";
import { useRouter } from "next/navigation";

export default function SignInPage() {
  const router = useRouter();

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    await authClient.signIn.email({
      email: formData.get("email") as string,
      password: formData.get("password") as string,
    });
    router.push("/");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" placeholder="邮箱" />
      <input name="password" type="password" placeholder="密码" />
      <button type="submit">登录</button>
    </form>
  );
}

注册页面(src/app/sign-up/page.tsx)逻辑类似,调用 authClient.signUp.email 即可。

七、GitHub OAuth 配置

  1. 登录 GitHub → Settings → Developer settings → OAuth Apps → New OAuth App

  2. 填写 Application name、Homepage URL(http://localhost:3000

  3. Authorization callback URL 填写 http://localhost:3000/api/auth/callback/github

  4. 注册后获取 Client ID ,生成 Client Secret ,填入 .env

在登录页面添加 GitHub 登录按钮:

tsx

复制代码
<button onClick={() => authClient.signIn.social({ provider: "github" })}>
  使用 GitHub 登录
</button>

八、会话管理与路由保护

Better Auth 同时支持服务端和客户端的 Session 获取。

服务端获取 Sessionsrc/app/page.tsx):

tsx

复制代码
import { auth } from "@/lib/auth";
import { headers } from "next/headers";

export default async function Home() {
  const session = await auth.api.getSession({
    headers: await headers(),
  });

  if (!session) {
    return <div>请先登录</div>;
  }

  return <div>欢迎,{session.user.name}</div>;
}

客户端获取 Session

tsx

复制代码
"use client";
import { authClient } from "@/lib/auth-client";

export default function ClientComponent() {
  const { data: session, isPending } = authClient.useSession();

  if (isPending) return <div>加载中...</div>;
  if (!session) return <div>请先登录</div>;

  return (
    <div>
      欢迎,{session.user.name}
      <button onClick={() => authClient.signOut()}>登出</button>
    </div>
  );
}

九、最终测试

  1. 启动项目:npm run dev

  2. 访问 /sign-up 注册新用户,注册成功后自动登录并跳转首页

  3. 访问 /sign-in 用邮箱密码登录

  4. 点击"使用 GitHub 登录",授权后自动登录

  5. 首页正确显示用户名,点击登出按钮退出登录

至此,一套完整的邮箱密码 + GitHub OAuth 登录注册系统已集成完毕,所有用户数据均存储在你自己的 Neon 数据库中,全程免费、无供应商锁定。

总结

Better Auth 通过 auth 后端实例 + authClient 前端客户端的双层设计,将认证逻辑封装成开箱即用的 API。开发者只需配置数据库和 OAuth 凭证,即可获得完整的登录注册能力。目前 Better Auth 已在 GitHub 上获得广泛关注,并提供了 50+ 插件支持 2FA、Passkey、组织管理、支付集成等进阶功能。

对于需要快速集成认证功能且希望数据自主可控的项目,Better Auth 是一个值得尝试的选择。