身份验证

2026年9月6日

登录别从零造。本篇按 Better Auth 记一条能跑通的集成:邮箱密码 + GitHub,数据放 PostgreSQL + Prisma。Auth.js、Clerk 是同类选项,选型看数据库和要不要托管。


为什么用它

  • 邮箱、OAuth、Session / Cookie 都有现成插件
  • 适配 Prisma、Drizzle,库可以是 Postgres / MySQL / SQLite / Mongo
  • Next、Hono 都有 handler

密钥、回调 URL 只放环境变量。


安装和 env

pnpm add better-auth prisma @prisma/client
pnpm add -D prisma
npx prisma init
bash
BETTER_AUTH_SECRET="用 openssl rand -base64 32 生成"
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL="postgresql://postgres:123456@localhost:5432/auth"
bash

auth 实例

src/lib/auth.ts

import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import prisma from "@/lib/prisma";

export const auth = betterAuth({
  database: prismaAdapter(prisma, { provider: "postgresql" }),
  emailAndPassword: { enabled: true },
});
ts

生成表结构:

npx auth@latest generate
npx prisma migrate dev --name auth
npx prisma generate
bash

会得到 UserSessionAccountVerification 一类模型。字段以生成结果为准,不要手抄过期 schema。


挂 Route Handler

app/api/auth/[...all]/route.ts

import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

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

客户端

import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000",
});

export const { signIn, signUp, useSession } = authClient;
ts

baseURL 要和 BETTER_AUTH_URL 一致。

"use client";

import { signIn, signUp } from "@/lib/auth-client";
import { useState } from "react";

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

  return (
    <>
      <button
        type="button"
        onClick={() => signUp.email({ email, password, name })}
      >
        注册
      </button>
      <button
        type="button"
        onClick={() => signIn.email({ email, password })}
      >
        登录
      </button>
    </>
  );
}
tsx

返回 { data, error },按 error 提示即可。


GitHub

  1. GitHub → Settings → Developer settings → OAuth App
  2. Callback:http://localhost:3000/api/auth/callback/github(生产换域名)
  3. env:GITHUB_CLIENT_IDGITHUB_CLIENT_SECRET
socialProviders: {
  github: {
    clientId: process.env.GITHUB_CLIENT_ID!,
    clientSecret: process.env.GITHUB_CLIENT_SECRET!,
  },
},
ts
await signIn.social({ provider: "github" });
ts

成功会跳到 GitHub 授权,回来带会话。保护页面用 useSession 或在服务端查 session,未登录 redirect('/login')。和前面 Proxy 里查 cookie 是同一类事。

下一篇:接口层用 Hono 挂进 Next。


参考文档