升級指南 (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()
文件) - Edge 相容
通用 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 組態非常相似。不同之處在於我們現在是在存放庫根目錄中的一個新檔案中執行此操作,並且我們匯出方法以便在其他地方使用。以下是 v5 組態檔的簡單範例。
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() Hook | useSession() Hook |
路由處理器 | 先前不支援 | 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 支援,如果您未使用 (先前可選的) oauth_token_secret
和 oauth_token
欄位,則可以將它們從 account
表格中移除。
此外,先前不常見的欄位 (例如 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 在 Proxy 後方執行時,這是必要的。當設定為 true 時,我們會信任 Proxy 傳遞至應用程式的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
等。
Cookies
next-auth
前綴已重新命名為authjs
。
總結
我們希望這次遷移對大家來說都能順利進行!如果您有任何問題或遇到任何困難,請隨時在 GitHub 上建立新的 issue,或是在 Discord 伺服器上與我們聊天。