nextjs-supabase-auth

nextjs-supabase-auth

熱門

Supabase Auth 與 Next.js App Router 的專業整合方案

4.3萬星標
6676分支
更新於 2026/7/15
SKILL.md
唯讀
名稱
nextjs-supabase-auth
描述

Supabase Auth 與 Next.js App Router 的專業整合方案

Next.js + Supabase Auth

Supabase Auth 與 Next.js App Router 的專業整合方案

Capabilities

  • nextjs-auth
  • supabase-auth-nextjs
  • auth-middleware
  • auth-callback

Prerequisites

  • 必要技能:nextjs-app-router, supabase-backend

Patterns

Supabase Client 設定

針對不同情境建立設定正確的 Supabase Client

使用時機:在 Next.js 專案中設定身分驗證

// lib/supabase/client.ts (瀏覽器端 Client)
'use client'
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

// lib/supabase/server.ts (伺服器端 Client)
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
  const cookieStore = await cookies()
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => {
            cookieStore.set(name, value, options)
          })
        },
      },
    }
  )
}

Auth Middleware

在 Middleware 中保護路由並自動刷新 Session

使用時機:需要進行路由權限控管或 Session 自動刷新

// middleware.ts
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
  let response = NextResponse.next({ request })

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => {
            response.cookies.set(name, value, options)
          })
        },
      },
    }
  )

  // 若 Session 已過期則自動更新
  const { data: { user } } = await supabase.auth.getUser()

  // 保護 dashboard 路由
  if (request.nextUrl.pathname.startsWith('/dashboard') && !user) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return response
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}

Auth Callback 路由

處理 OAuth 回呼並將驗證碼(code)兌換為 Session

使用時機:整合 OAuth 第三方登入(Google、GitHub 等)

// app/auth/callback/route.ts
import { createClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url)
  const code = searchParams.get('code')
  const next = searchParams.get('next') ?? '/'

  if (code) {
    const supabase = await createClient()
    const { error } = await supabase.auth.exchangeCodeForSession(code)
    if (!error) {
      return NextResponse.redirect(`${origin}${next}`)
    }
  }

  return NextResponse.redirect(`${origin}/auth/error`)
}

Server Action 驗證處理

在 Server Actions 中執行身分驗證相關操作

使用時機:從 Server Components 進行登入、登出或註冊

// app/actions/auth.ts
'use server'
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'

export async function signIn(formData: FormData) {
  const supabase = await createClient()
  const { error } = await supabase.auth.signInWithPassword({
    email: formData.get('email') as string,
    password: formData.get('password') as string,
  })

  if (error) {
    return { error: error.message }
  }

  revalidatePath('/', 'layout')
  redirect('/dashboard')
}

export async function signOut() {
  const supabase = await createClient()
  await supabase.auth.signOut()
  revalidatePath('/', 'layout')
  redirect('/')
}

在 Server Component 取得使用者資料

在 Server Components 中讀取已登入的使用者資訊

使用時機:要在伺服器端渲染特定使用者的專屬內容

// app/dashboard/page.tsx
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'

export default async function DashboardPage() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()

  if (!user) {
    redirect('/login')
  }

  return (
    <div>
      <h1>Welcome, {user.email}</h1>
    </div>
  )
}

Validation Checks

使用 getSession() 進行驗證檢查

嚴重程度:ERROR

錯誤訊息:getSession() 不會驗證 JWT。請改用 getUser() 來確保身分驗證檢查的安全性。

修復動作:在關鍵的安全檢查中,將 getSession() 替換為 getUser()

缺少 OAuth Callback 路由

嚴重程度:ERROR

錯誤訊息:使用了 OAuth 登入但缺少 app/auth/callback/route.ts 回呼路由

修復動作:建立 app/auth/callback/route.ts 來處理 OAuth 的重導向邏輯

在伺服器端環境誤用 Browser Client

嚴重程度:ERROR

錯誤訊息:在 Server 環境使用了 Browser Client。請改用 createServerClient。

修復動作:從 @supabase/ssr 匯入並使用 createServerClient

受保護路由未設定 Middleware

嚴重程度:WARNING

錯誤訊息:未找到 middleware.ts。建議加入 Middleware 以實現路由保護。

修復動作:建立 middleware.ts 來保護受限制路由並刷新 Session

硬編碼的 Auth 重導向 URL

嚴重程度:WARNING

錯誤訊息:重導向使用了硬編碼的 localhost。請改用 origin 以提升不同環境下的彈性。

修復動作:改用 window.location.origin 或 process.env.NEXT_PUBLIC_SITE_URL

Auth 呼叫未處理錯誤

嚴重程度:WARNING

錯誤訊息:執行 Auth 操作時缺少錯誤處理。請務必檢查是否回傳錯誤。

修復動作:透過解構取得 { data, error } 並加入錯誤處理邏輯

Auth Action 未刷新快取

嚴重程度:WARNING

錯誤訊息:Auth Action 操作後未呼叫 revalidatePath,導致快取仍顯示過期的驗證狀態。

修復動作:在 Auth 操作成功後加上 revalidatePath('/', 'layout')

純前端(Client-Side)路由保護

嚴重程度:WARNING

錯誤訊息:僅在客戶端做路由保護會導致畫面閃爍(Flash of Content)。建議改用 Middleware。

修復動作:將保護邏輯移至 middleware.ts 以提供更好的使用者體驗

Collaboration

任務分派觸發條件

  • database|rls|queries|tables -> supabase-backend(身分驗證需要資料庫層配合)
  • route|page|component|layout -> nextjs-app-router(身分驗證需要 Next.js 開發模式)
  • deploy|production|vercel -> vercel-deployment(身分驗證需要正式環境部署設定)
  • ui|form|button|design -> frontend(身分驗證需要 UI 元件)

完整 Auth 技術棧流程

Skills: nextjs-supabase-auth, supabase-backend, nextjs-app-router, vercel-deployment

工作流程:

1. 資料庫建置 (supabase-backend)
2. 身分驗證實作 (nextjs-supabase-auth)
3. 路由權限保護 (nextjs-app-router)
4. 部署參數設定 (vercel-deployment)

受保護的 SaaS 應用流程

Skills: nextjs-supabase-auth, stripe-integration, supabase-backend

工作流程:

1. 使用者身分驗證 (nextjs-supabase-auth)
2. 客戶資料同步 (stripe-integration)
3. 訂閱權限控管 (supabase-backend)

Related Skills

適合搭配:nextjs-app-router, supabase-backend

使用時機

  • 使用者提及或暗示:supabase auth next
  • 使用者提及或暗示:authentication next.js
  • 使用者提及或暗示:login supabase
  • 使用者提及或暗示:auth middleware
  • 使用者提及或暗示:protected route
  • 使用者提及或暗示:auth callback
  • 使用者提及或暗示:session management

Limitations

  • 僅在任務需求明確符合上述涵蓋範疇時使用此 Skill。
  • 請勿將產出結果直接取代特定環境下的實際驗證、測試或專家審查。
  • 若缺乏必要的輸入資料、執行權限、安全邊界或成功判定標準,請立即暫停並要求進一步說明。