从 NextAuth.js迁移到Better Auth

在本文中,我们将介绍从 NextAuth.js 迁移到 Better Auth 的步骤,确保不会丢失数据或功能。虽然本指南主要针对 Next.js,但也可以应用于其他框架。


开始之前

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


映射现有列

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

用户模式

你现有的用户模式可能与 Better Auth 兼容,因此不需要更改。

会话模式

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

  • expiresexpiresAt
  • sessionTokentoken
auth.ts
export const auth = betterAuth({
    // 其他配置
    session: {
        fields: {
            expiresAt: "expires", // 将你现有的 `expires` 字段映射到 Better Auth 的 `expiresAt`
            token: "sessionToken" // 将你现有的 `sessionToken` 字段映射到 Better Auth 的 `token`
        }
    },
});

确保你的会话模式上有 createdAtupdatedAt 字段。

账户模式

在账户模式中映射这些字段:

  • providerAccountIdaccountId
  • refresh_tokenrefreshToken
  • access_tokenaccessToken
  • access_token_expiresaccessTokenExpiresAt
  • id_tokenidToken

移除 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