Auth.js (NextAuth v5) 模式 是做什麼的?
快速指南: 在根目錄的
auth.ts檔案中配置 Auth.js,從NextAuth()匯出{ auth, handlers, signIn, signOut }。統一使用auth()函數(適用於伺服器元件、路由處理器、中間件)。預設 session 策略為 JWT(基於 Cookie);若要使用持久化 session,則需加上資料庫配接器。透過中間件或基於頁面的auth()檢查來保護路由。
<critical_requirements>
重要:使用此技能前
所有程式碼必須遵守
CLAUDE.md中的專案慣例(kebab-case、命名匯出、匯入順序、import type、命名常數)
(你必須在根目錄的 auth.ts 檔案中配置 Auth.js,並從 NextAuth() 匯出 { auth, handlers, signIn, signOut })
(你必須使用統一的 auth() 函數來存取伺服器端 session - 不得使用已棄用的 getServerSession()、getSession() 或 getToken())
(你必須使用 AUTH_SECRET 環境變數 - NEXTAUTH_SECRET 在 v5 中已棄用)
(你必須對提供者憑證使用 AUTH_ 前綴的環境變數(例如 AUTH_GITHUB_ID、AUTH_GITHUB_SECRET)- 它們會被自動偵測)
(當在 middleware 中使用資料庫 session 時,你必須將 auth 配置拆分為 auth.config.ts(Edge 相容)和 auth.ts(搭配配接器))
(你必須在伺服器動作(Server Actions)和 API 路由中檢查 session - 僅靠 middleware 不足以進行授權)
</critical_requirements>
自動偵測: Auth.js, NextAuth, next-auth, authjs, auth.ts, auth.config.ts, NextAuth(), signIn, signOut, auth(), handlers, SessionProvider, useSession, AUTH_SECRET, OAuth provider, credentials provider, database adapter, @auth/prisma-adapter, @auth/drizzle-adapter, authorized callback, jwt callback, session callback, proxy auth, middleware auth
使用時機:
- 為 Next.js、SvelteKit、Express 或 Qwik 應用程式加入驗證
- 實作 OAuth 登入(GitHub、Google、Discord 等),內建超過 80 個提供者
- 建立電子郵件/魔法連結驗證流程
- 需要 JWT 或資料庫支援的 session 管理
- 需要 Edge 相容 middleware 驗證的專案
不應使用時機:
- 從頭開始建立自訂驗證系統(Auth.js 意見領袖性強)
- 需要立即可用的精細組織/團隊管理功能
- 沒有 Web 前端的純行動應用程式
- 需要自託管且具外掛架構的驗證
涵蓋的主要模式:
- Auth 配置(
auth.ts、auth.config.ts) - OAuth 提供者(GitHub、Google、Credentials、Email)
- Session 策略(JWT 與 資料庫)
- Session 存取(伺服器元件、路由處理器、用戶端元件)
- 中間件/代理路由保護
- 資料庫配接器(Prisma、Drizzle)
- 回呼(jwt、session、signIn、redirect)
- 基於角色的存取控制
- Edge 相容性拆分配置
詳細資源:
- 關於決策框架與反模式,請參閱 reference.md
核心模式:
- examples/core.md - Auth 配置、提供者、回呼
- examples/session.md - Session 策略、Session 存取模式
- examples/middleware.md - 路由保護、中間件、Edge 相容性
- examples/database.md - 資料庫配接器、Prisma、Drizzle
- examples/patterns.md - 基於角色的存取、魔法連結、帳戶連結
理念
Auth.js (v5) 將驗證整合成一個單一、統一的 API。auth() 函數在伺服器端使用上,取代了 v4 的 getServerSession、getSession、withAuth 和 getToken。useSession() 仍然是正確的用戶端 API。配置位於根目錄檔案中,而非 API 路由中。
核心原則:
- 框架無關 - 可與 Next.js、SvelteKit、Express、Qwik 搭配使用
- 統一 API - 所有伺服器端情境均使用單一
auth()函數 - 提供者生態系統 - 超過 80 個內建 OAuth 提供者,會自動偵測
AUTH_*環境變數 - 預設 JWT - 加密 Cookie 中的無狀態 session,無需資料庫
- Edge 相容 - Middleware 使用拆分配置在 Edge runtime 上運行(Next.js 16 proxy 在 Node.js 上運行)
- 漸進式複雜度 - 從 OAuth 開始,加入資料庫配接器,再自訂回呼
核心模式
模式 1:Auth 配置
中央配置檔案從 NextAuth() 匯出你所需的一切。
基本 OAuth 設定
// auth.ts
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, // 自動偵測 AUTH_GITHUB_ID 和 AUTH_GITHUB_SECRET
Google, // 自動偵測 AUTH_GOOGLE_ID、AUTH_GOOGLE_SECRET
],
});
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth";
export const { GET, POST } = handlers;
為何良好: 單一配置檔案匯出所有 auth 工具,提供者自動偵測 AUTH_* env vars,API 路由最簡化
環境變數
# .env.local
AUTH_SECRET="generate-with-npx-auth-secret" # 必要
AUTH_GITHUB_ID="your-github-client-id" # 被 GitHub 提供者自動偵測
AUTH_GITHUB_SECRET="your-github-secret" # 被 GitHub 提供者自動偵測
AUTH_GOOGLE_ID="your-google-id" # 被 Google 提供者自動偵測
AUTH_GOOGLE_SECRET="your-google-secret"
為何良好: v5 中標準化了 AUTH_ 前綴,AUTH_SECRET 取代了已棄用的 NEXTAUTH_SECRET,提供者會自動偵測憑證
模式 2:提供者
Auth.js 支援 OAuth、電子郵件/魔法連結和憑證驗證。超過 80 個內建 OAuth 提供者會自動偵測 AUTH_* env vars。
// OAuth:自訂 profile 映射
GitHub({
profile(profile) {
return {
id: String(profile.id),
name: profile.name ?? profile.login,
role: "user",
};
},
});
// Credentials:驗證輸入,失敗時回傳 null
Credentials({
async authorize(credentials) {
const parsed = LoginSchema.safeParse(credentials);
if (!parsed.success) return null;
const user = await getUserByEmail(parsed.data.email);
if (
!user ||
!(await verifyPassword(parsed.data.password, user.hashedPassword))
)
return null;
return { id: user.id, name: user.name, email: user.email };
},
});
關鍵規則: 在查詢資料庫前驗證輸入,始終對密碼進行雜湊處理,失敗時回傳 null(切勿拋出錯誤 - 會洩漏資訊)。完整實作請參閱 examples/core.md。
模式 3:回呼
四個回呼可自訂 auth 行為。資料流動:jwt 回呼(豐富 token)-> session 回呼(暴露給客戶端)。
callbacks: {
jwt({ token, user }) {
if (user) { token.id = user.id; token.role = user.role ?? "user"; }
return token;
},
session({ session, token }) {
session.user.id = token.id as string;
session.user.role = token.role as string;
return session;
},
}
關鍵規則: jwt 回呼在每次呼叫 auth() 時都會執行(保持輕量),user 參數僅在登入時存在,切勿將 OAuth token 暴露給客戶端。包含 signIn 和 redirect 的完整回呼實作請參閱 examples/core.md。
模式 4:Session 存取
統一的 auth() 函數在伺服器端使用上,取代了 v4 的 getServerSession、getSession 和 getToken。useSession() 保留給用戶端元件使用。
| Context | 如何存取 session |
|---|---|
| Server Component | const session = await auth() |
| Route Handler | export const GET = auth(function GET(req) { req.auth }) |
| Server Action | const session = await auth() |
| Middleware/Proxy | export { auth as middleware } 或 authorized 回呼 |
| Client Component | useSession()(需要在 layout 中使用 SessionProvider) |
關鍵規則: 伺服器端匯入來自 @/auth,客戶端匯入來自 next-auth/react。切勿在 Client Component 中呼叫 auth()。完整實作請參閱 examples/session.md。
模式 5:登入 / 登出動作
兩種方法:Server Actions(建議,漸進增強)或客戶端。
// 伺服器端(建議):從 @/auth 匯入,在表單中使用 Server Actions
import { signIn, signOut } from "@/auth";
// 在表單動作中:await signIn("github", { redirectTo: "/dashboard" })
// 在表單動作中:await signOut({ redirectTo: "/" })
// 客戶端:從 next-auth/react 匯入,使用 onClick 處理器
import { signIn, signOut } from "next-auth/react";
// onClick: signIn("github", { callbackUrl: "/dashboard" })
關鍵規則: 伺服器端使用 redirectTo,客戶端使用 callbackUrl。signIn() 會在內部拋出 NEXT_REDIRECT 例外——不要試圖用 try/catch 包裹並期待回傳值。完整實作請參閱 examples/core.md。
模式 6:TypeScript 擴充
透過 types/next-auth.d.ts 中的宣告合併來擴充 session 和 JWT 型別。使用 & DefaultSession["user"] 在 Session、User 和 JWT 介面上宣告自訂欄位(例如 id、role)以保留預設值。完整的型別宣告範例請參閱 examples/core.md。
整合指南
Auth.js 是驗證層。 它處理身份驗證、session 管理和路由保護。它不處理授權邏輯(角色檢查、權限系統)——那是應用程式程式碼的範疇。
框架支援: Auth.js 透過特定框架套件(next-auth、@auth/sveltekit、@auth/express)與多種 Web 框架搭配使用。
資料庫配接器: 對於資料庫 session,Auth.js 提供了與你的 ORM 整合的配接器套件(@auth/prisma-adapter、@auth/drizzle-adapter 等)。請參閱 examples/database.md。
Session 策略取決於你的需求:
- JWT(預設) - 無需資料庫,可在 Edge 上運作,無狀態
- 資料庫 - 需要配接器、伺服器端 session 儲存,支援即時撤銷
Auth.js 不處理: 精細授權/RBAC、速率限制,或超出 auth 範圍的資料庫查詢——這些是應用程式層級的事務。
<red_flags>
紅旗標誌
- 使用
getServerSession(authOptions)—— 在 v5 中已棄用;請使用auth.ts中的auth() - 使用
NEXTAUTH_SECRET或NEXTAUTH_URL—— 已棄用;請使用AUTH_SECRET(URL 會自動偵測) - Credentials 提供者未加速率限制 —— 容易受到暴力攻擊
- 透過 session 回呼將 OAuth token 暴露給客戶端 —— 將
accessToken/refreshToken僅保留在伺服器端 - Middleware/proxy 作為唯一授權 —— 在渲染前執行,但無法取代 Server Actions/API 路由中的逐路由檢查
- 在 middleware 中匯入資料庫配接器 —— 資料庫 ORM 無法在 Edge runtime 上執行(Next.js 14/15);將配置拆分為
auth.config.ts+auth.ts - 將
signIn()包裹在 try/catch 中 —— 它會在內部拋出 NEXT_REDIRECT 例外(這是故意的) - JWT 回呼每次呼叫都查詢資料庫 —— 在每次呼叫
auth()時都會執行;請保持輕量
完整的反模式列表、陷阱和遷移表請參閱 reference.md。
</red_flags>
<critical_reminders>
重要提醒
所有程式碼必須遵守
CLAUDE.md中的專案慣例
(你必須在根目錄的 auth.ts 檔案中配置 Auth.js,並從 NextAuth() 匯出 { auth, handlers, signIn, signOut })
(你必須使用統一的 auth() 函數來存取伺服器端 session - 不得使用已棄用的 getServerSession()、getSession() 或 getToken())
(你必須使用 AUTH_SECRET 環境變數 - NEXTAUTH_SECRET 在 v5 中已棄用)
(你必須對提供者憑證使用 AUTH_ 前綴的環境變數(例如 AUTH_GITHUB_ID、AUTH_GITHUB_SECRET)- 它們會被自動偵測)
(當在 middleware 中使用資料庫 session 時,你必須將 auth 配置拆分為 auth.config.ts(Edge 相容)和 auth.ts(搭配配接器))
(你必須在伺服器動作(Server Actions)和 API 路由中檢查 session - 僅靠 middleware 不足以進行授權)
未能遵守這些規則將導致驗證失敗、暴露已棄用的模式,或造成安全漏洞。
</critical_reminders>