升级指南 (NextAuth.js v5)
本指南仅适用于 Next.js 用户的 next-auth
升级。如果您没有升级到 next-auth@5
,请随时跳到下一部分,安装。
NextAuth.js 版本 5是对 next-auth
包的重大重写,也就是说,我们尽可能减少了重大变更。对于所有其他情况,本文档将指导您完成迁移过程。
使用 beta
标签安装最新版本的 next-auth
开始。
npm install next-auth@beta
新功能
主要变更
- App Router优先(
pages/
仍然受支持) - 预览部署上的 OAuth 支持(了解更多)
- 简化的设置(共享配置、推断的 环境变量)
- 新的
account()
提供者回调(account()
文档) - 边缘兼容
通用 auth()
- 在任何地方进行身份验证的单一方法
- 使用
auth()
而不是getServerSession
、getSession
、withAuth
、getToken
和useSession
(了解更多)
重大变更
- Auth.js 现在建立在
@auth/core
上,具有更严格的 OAuth/OIDC 规范合规性,这可能会破坏一些现有的 OAuth 提供者。有关更多详细信息,请参阅我们的 开放问题。 - OAuth 1.0 支持已弃用。
- 现在所需的最低 Next.js 版本为 14.0。
- 导入
next-auth/next
已替换。有关更多详细信息,请参阅 服务器端身份验证。 - 导入
next-auth/middleware
已替换。有关更多详细信息,请参阅 服务器端身份验证。 - 当
idToken: boolean
选项设置为false
时,它不会完全禁用 ID 令牌。相反,它会向next-auth
发出信号,以便也访问userinfo_endpoint
获取最终用户数据。以前,idToken: false
选择完全不检查id_token
的有效性。
迁移
配置文件
我们的目标之一是避免从一个文件中导出配置并在整个应用程序中将其作为 authOptions
传递。为了实现这一点,我们决定将配置文件移到存储库的根目录,并让它导出您可以在其他地方使用的必要函数。(auth
、signIn
、signOut
、handlers
等)。
配置文件应该与您以前的基于路由的 Auth.js 配置非常相似。除了我们现在将其放在存储库根目录中的一个新文件中,并且我们正在导出将在应用程序的其他地方使用的方法之外。
import NextAuth from "next-auth"
import GitHub from "next-auth/providers/github"
import Google from "next-auth/providers/google"
export const { auth, handlers, signIn, signOut } = NextAuth({
providers: [GitHub, Google],
})
关于新配置需要注意的一些事项
- 这现在位于存储库根目录中的名为
auth.ts
的文件中。它实际上可以命名为任何东西,但您将在整个应用程序中从此处导入导出的方法,因此我们建议将其保持简短。 - 无需安装
@auth/core
来从其中导入提供者定义,这些定义来自next-auth
本身。 - 传递给
NextAuth()
函数的配置对象与以前相同。 - 从
NextAuth()
函数调用中返回的导出方法是新的,将在应用程序的其他地方使用。
旧的配置文件包含在 API 路由中(pages/api/auth/[...nextauth].ts
/ app/api/auth/[...nextauth]/route.ts
),现在变得更短了。**这些导出旨在用于 App Router API 路由**,但如果您正在逐步迁移,您的应用程序的其余部分可以保留在 Pages Router 中!
import { handlers } from "@/auth"
export const { GET, POST } = handlers
服务器端身份验证
Auth.js 过去在服务器端进行身份验证的方法有好几种,因此我们尽力将其简化。
现在 Next.js 组件默认情况下是**服务器优先**,并且由于在使用标准 Web API 方面的投入,我们能够将身份验证过程简化为大多数情况下的一次 auth()
函数调用。
身份验证方法
请参见下表以了解更改摘要。其下方是 diff
示例,说明如何在各种环境和上下文中使用新的 auth()
方法。
其中 | v4 | v5 |
---|---|---|
服务器组件 | getServerSession(authOptions) | auth() 调用 |
中间件 | withAuth(middleware, 部分 authOptions) 包装器 | auth 导出 / auth() 包装器 |
客户端组件 | useSession() 钩子 | useSession() 钩子 |
路由处理程序 | 以前不支持 | auth() 包装器 |
API 路由(Edge) | 以前不支持 | auth() 包装器 |
API 路由(Node.js) | getServerSession(req, res, authOptions) | auth(req, res) 调用 |
API 路由(Node.js) | getToken(req) (无会话轮换) | auth(req, res) 调用 |
getServerSideProps | getServerSession(ctx.req, ctx.res, authOptions) | auth(ctx) 调用 |
getServerSideProps | getToken(ctx.req) (无会话轮换) | auth(req, res) 调用 |
详情
Auth.js v4 一直支持通过 getServerSession
在服务器组件中读取会话。现在,它已简化为相同的 auth()
函数。
- import { authOptions } from "pages/api/auth/[...nextauth]"
- import { getServerSession } from "next-auth/next"
+ import { auth } from "@/auth"
export default async function Page() {
- const session = await getServerSession(authOptions)
+ const session = await auth()
return (<p>Welcome {session?.user.name}!</p>)
}
适配器
适配器包
从 next-auth
v5 开始,您现在应该从 @auth/*-adapter
范围安装数据库适配器,而不是 @next-auth/*-adapter
。数据库适配器不依赖于任何 Next.js 功能,因此将它们移到此新范围更有意义。
- npm install @next-auth/prisma-adapter
+ npm install @auth/prisma-adapter
数据库迁移
NextAuth.js v5 **不会对数据库模式引入任何重大更改**。但是,由于 OAuth 1.0 支持已删除,因此如果您未使用它们,可以从 account
表中删除(以前可选的)oauth_token_secret
和 oauth_token
字段。
此外,以前不常见的字段(如 GitHub 的 refresh_token_expires_in
字段)需要添加到 account
表中。现在不再需要这样做,如果您未使用它,可以将其删除。如果您确实使用它,请确保通过新的 account()
回调 返回它。
Edge 兼容性
虽然 Auth.js 严格使用标准 Web API(因此可以在任何支持它们的環境中运行),但您依赖的一些库或 ORM(对象关系映射)包可能尚未准备好。在这种情况下,您可以将身份验证配置拆分成多个文件。
Auth.js 支持两种 会话策略。当您使用适配器时,它将默认使用 database
策略。**除非您的数据库及其适配器与 Edge 运行时/基础结构兼容,否则您将无法使用 "database"
会话策略**。
例如,如果您使用的适配器依赖于尚未与 Edge 运行时兼容的 ORM/库,以下是一个示例,其中我们强制使用 jwt
策略并拆分配置,以防止库尝试在 Edge 环境(如中间件中)访问数据库。
以下文件名只是一种约定,您可以随意命名它们。
- 创建一个
auth.config.ts
文件,该文件导出包含您的 Auth.js 配置选项的对象。您可以在此处放置所有**不依赖适配器**的通用配置。注意,这里只导出一个配置对象,我们没有在此处调用NextAuth()
。
import GitHub from "next-auth/providers/github"
import type { NextAuthConfig } from "next-auth"
export default { providers: [GitHub] } satisfies NextAuthConfig
- 接下来,创建一个
auth.ts
文件,并添加您的适配器和jwt
会话策略。这是您将在应用程序其他地方(中间件除外)导入的auth.ts
配置文件。
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
import authConfig from "./auth.config"
const prisma = new PrismaClient()
export const { auth, handlers, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
session: { strategy: "jwt" },
...authConfig,
})
- 在您的中间件文件中,从第一个
auth.config.ts
文件中导入配置对象,并使用它来延迟初始化 Auth.js。实际上,使用所有通用选项分别初始化 Auth.js,但**不使用与 Edge 不兼容的适配器**。
import authConfig from "./auth.config"
import NextAuth from "next-auth"
// Use only one of the two middleware options below
// 1. Use middleware directly
// export const { auth: middleware } = NextAuth(authConfig)
// 2. Wrapped middleware option
const { auth } = NextAuth(authConfig)
export default auth(async function middleware(req: NextRequest) {
// Your custom middleware logic goes here
})
以上只是一个示例。**主要思想**是将与 Edge 兼容的配置部分与其余部分分开,只在中间件/Edge 页面/路由中导入与 Edge 兼容的部分。例如,您可以在 Prisma 文档 中阅读有关此解决方法的更多信息。
请与您的库/数据库/ORM 的维护者联系,了解他们是否计划支持 Edge 运行时/基础结构。
有关 Edge 兼容性以及 Auth.js 如何融入其中的更多信息,请查看我们的 Edge 兼容性文章。
环境变量
**环境变量没有重大更改**,但我们清理了一些内容,使其中一些内容变得不必要。因此,我们想分享一些有关环境变量的最佳实践。
- 所有环境变量都应该以
AUTH_
为前缀,NEXTAUTH_
现在不再使用。 - 如果您使用此语法命名提供程序
secret
/clientId
变量,例如AUTH_GITHUB_SECRET
和AUTH_GITHUB_ID
,它们将自动检测到,您无需显式地将它们传递到提供程序的配置中。 - 在大多数环境中,
NEXTAUTH_URL
/AUTH_URL
现在不再严格必要。我们将根据请求头自动检测主机。 - 环境变量
AUTH_TRUST_HOST
的作用与在 Auth.js 配置中设置trustHost: true
相同。当在代理后面运行 Auth.js 时,这是必要的。如果设置为 true,我们将信任代理传递给应用程序的X-Forwarded-Host
和X-Forwarded-Proto
标头,以自动检测主机 URL (AUTH_URL
)。 - 环境变量
AUTH_SECRET
是**唯一真正必要的变量**。如果您已设置环境变量,则无需另外将此值作为secret
配置选项传递到您的配置中。
有关环境变量和环境变量推断的更多信息,请查看我们的 环境变量 页面。
TypeScript
NextAuthOptions
已重命名为NextAuthConfig
- 以下类型现在从所有框架包(如
next-auth
和@auth/sveltekit
)导出
export type {
Account,
DefaultSession,
Profile,
Session,
User,
} from "@auth/core/types"
- 所有
Adapter
类型也从框架包中的/adapters
重新导出,例如,从next-auth/adapters
、@auth/sveltekit/adapters
等。
Cookie
- 前缀
next-auth
已重命名为authjs
。
总结
我们希望这次迁移能顺利进行!如果您有任何疑问或遇到任何问题,请随时在 GitHub 上创建一个 新问题,或者在 Discord 服务器上与我们聊天。