从 NextAuth.js 迁移到 Better Auth

在本指南中,我们将逐步介绍如何将项目从 NextAuth.js 迁移到 Better Auth,确保不丢失任何数据或功能。虽然本指南主要关注 Next.js,但它也适用于其他框架。


开始之前

在开始迁移过程之前,请先在项目中设置 Better Auth。按照安装指南开始操作。


映射现有列

你可以将现有的数据库列名映射到 Better Auth 预期的结构,而不是修改现有的数据库列名。这样可以保留当前的数据库模式。

用户模式

在用户模式中映射以下字段:

  • (next-auth v4) emailVerified:datetime → boolean

会话模式

在会话模式中映射以下字段:

  • expiresexpiresAt
  • sessionTokentoken
  • (next-auth v4) 添加 createdAt,类型为 datetime
  • (next-auth v4) 添加 updatedAt,类型为 datetime
auth.ts
export const auth = betterAuth({
    // 其他配置
    session: {
        fields: {
            expiresAt: "expires", // 将现有的 `expires` 字段映射到 Better Auth 的 `expiresAt`
            token: "sessionToken" // 将现有的 `sessionToken` 字段映射到 Better Auth 的 `token`
        }
    },
});

确保在会话模式中包含 createdAtupdatedAt 字段。

账户模式映射

在账户模式中映射以下字段:

  • (next-auth v4) providerproviderId
  • providerAccountIdaccountId
  • refresh_tokenrefreshToken
  • access_tokenaccessToken
  • (next-auth v3) access_token_expiresaccessTokenExpiresAt 且 int → datetime
  • (next-auth v4) expires_ataccessTokenExpiresAt 且 int → datetime
  • id_tokenidToken
  • (next-auth v4) 添加 createdAt 字段,类型为 datetime
  • (next-auth v4) 添加 updatedAt 字段,类型为 datetime

移除 session_statetypetoken_type 字段,因为 Better Auth 不需要这些字段。

auth.ts
export const auth = betterAuth({
    // 其他配置
    account: {
        fields: {
            accountId: "providerAccountId",
            refreshToken: "refresh_token",
            accessToken: "access_token",
            accessTokenExpiresAt: "access_token_expires",
            idToken: "id_token",
        }
    },
});

注意: 如果使用 ORM 适配器,可以在模式文件中映射这些字段。

Prisma 示例:

schema.prisma
model Session {
    id          String   @id @default(cuid())
    expiresAt   DateTime @map("expires") // 将现有的 `expires` 字段映射到 Better Auth 的 `expiresAt`
    token       String   @map("sessionToken") // 将现有的 `sessionToken` 字段映射到 Better Auth 的 `token`
    userId      String
    user        User     @relation(fields: [userId], references: [id])
}

确保在账户模式中包含 createdAtupdatedAt 字段。

更新路由处理器

app/api/auth 文件夹中,将 [...nextauth] 文件重命名为 [...all] 以避免混淆。然后,按如下方式更新 route.ts 文件:

app/api/auth/[...all]/route.ts
import { toNextJsHandler } from "better-auth/next-js";
import { auth } from "~/server/auth";

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

更新客户端

lib 文件夹中创建一个名为 auth-client.ts 的文件。添加以下代码:

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

export const authClient = createAuthClient({
    baseURL: process.env.BASE_URL! // 如果 API 基础 URL 与前端匹配,此项为可选
});

export const { signIn, signOut, useSession } = authClient;

社交登录功能

更新你的社交登录功能以使用 Better Auth。例如,对于 Discord:

import { signIn } from "~/lib/auth-client";

export const signInDiscord = async () => {
    const data = await signIn.social({
        provider: "discord"
    });
    return data;
};

更新 useSession 调用

useSession 调用替换为 Better Auth 的版本。示例:

Profile.tsx
import { useSession } from "~/lib/auth-client";

export const Profile = () => {
    const { data } = useSession();
    return (
        <div>
            <pre>
                {JSON.stringify(data, null, 2)}
            </pre>
        </div>
    );
};

服务端会话处理

使用 auth 实例在服务器上获取会话数据:

actions.ts
"use server";

import { auth } from "~/server/auth";
import { headers } from "next/headers";

export const protectedAction = async () => {
    const session = await auth.api.getSession({
        headers: await headers(),
    });
};

中间件

要使用中间件保护路由,请参考 Next.js 中间件指南

总结

恭喜!您已成功从 NextAuth.js 迁移到 Better Auth。如需查看包含多种身份验证方法的完整实现,请查看 演示仓库

Better Auth 提供了更高的灵活性和更多功能——请务必查阅 文档 以解锁其全部潜力。

On this page