Communitygithub.com

Auth.js (NextAuth v5) 模式

Auth.js (NextAuth v5) 驗證模式——配置、提供者、Session 策略、中間件、資料庫配接器、基於角色的存取、Edge 相容性

Auth.js (NextAuth v5) 模式 是什麼?

此技能提供使用 Auth.js (NextAuth v5) 在 Next.js 應用程式中實作驗證的全面模式與指引。它涵蓋了從基本 OAuth 設定到進階主題(如資料庫 session、基於角色的存取控制與 Edge 相容性)的所有內容。此技能強調一套統一的 API,其中單一的 `auth()` 函數取代了 v4 中多個已棄用的函數,適用於所有伺服器端情境。用戶端元件則繼續使用 `useSession()`。配置集中在根目錄的 `auth.ts` 檔案中,其中匯出 `{ auth, handlers, signIn, signOut }`。此技能支援約 80 個內建的 OAuth 提供者,這些提供者會自動偵測 `AUTH_*` 環境變數,並詳細說明 JWT(預設,無狀態)與資料庫 session 策略之間的權衡。此外,它也針對常見陷阱(例如在中間件中匯入資料庫配接器、使用已棄用的變數,以及不正確地處理 `signIn()` 的錯誤)提供了重要的「紅旗」注意事項。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agents-inc/skills/tree/HEAD/src/skills/api-auth-nextauth

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

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 相容性拆分配置

詳細資源:

核心模式:


理念

Auth.js (v5) 將驗證整合成一個單一、統一的 API。auth() 函數在伺服器端使用上,取代了 v4 的 getServerSession、getSession、withAuth 和 getToken。useSession() 仍然是正確的用戶端 API。配置位於根目錄檔案中,而非 API 路由中。

核心原則:

  1. 框架無關 - 可與 Next.js、SvelteKit、Express、Qwik 搭配使用
  2. 統一 API - 所有伺服器端情境均使用單一 auth() 函數
  3. 提供者生態系統 - 超過 80 個內建 OAuth 提供者,會自動偵測 AUTH_* 環境變數
  4. 預設 JWT - 加密 Cookie 中的無狀態 session,無需資料庫
  5. Edge 相容 - Middleware 使用拆分配置在 Edge runtime 上運行(Next.js 16 proxy 在 Node.js 上運行)
  6. 漸進式複雜度 - 從 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 Componentconst session = await auth()
Route Handlerexport const GET = auth(function GET(req) { req.auth })
Server Actionconst session = await auth()
Middleware/Proxyexport { auth as middleware } 或 authorized 回呼
Client ComponentuseSession()(需要在 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>

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

相關技能