使用 Supabase Auth 來為您的專案建置身分驗證系統,在架構設計、核心觀念、整合方法以及上線生產環境時,以下是您需要掌握的關鍵資訊。
1. 核心架構與安全機制
- GoTrue 與 JWT 機制:Supabase Auth 底層是基於開源的 GoTrue 身分驗證 API。當使用者登入成功後,Supabase 會核發兩種憑證:代表使用者身分與權限的 JWT 存取權杖(Access Token),以及用於延長登入狀態的 更新權權杖(Refresh Token)。
- 與 PostgreSQL RLS(資料列級安全性)整合:這是使用 Supabase 最核心的安全設計。用戶登入後,客戶端 SDK 發送的所有資料庫請求都會自動帶上該使用者的 JWT。在 PostgreSQL 中啟用 RLS(Row Level Security) 後,您可以使用
auth.uid()函數來驗證使用者身分。例如,限制使用者只能存取自己資料的 RLS 策略:CREATE POLICY "使用者只能操作自己的資料" ON profiles FOR ALL USING (auth.uid() = user_id); - 兩種 Client 權限:
anon_key(公開匿名金鑰):安全防護強度低,僅能在開啟 RLS 的情況下供前端或客戶端使用。service_role_key(伺服器管理金鑰):擁有繞過所有 RLS 策略的最高管理權限,絕對不能洩漏到前端或瀏覽器中。
2. 支援的身分驗證方式
- 帳號密碼:傳統的 Email 與密碼註冊與登入。
- 無密碼驗證(Passwordless):
- Magic Link:發送含有一次性登入連結的 Email 到使用者信箱。
- 電話簡訊(OTP):支援透過 Twilio、MessageBird 等簡訊提供商發送驗證碼。
- Passkeys(生物辨識,支援 WebAuthn):支援使用 FaceID、TouchID、裝置 PIN 碼或實體安全金鑰登入,具備強大的防釣魚安全性。
- OAuth 2.0 第三方登入:支援 Google、GitHub、Apple、Discord 等數十種主流平台。亦支援自訂 OIDC(OpenID Connect)提供商,方便對接自建的身分驗證系統。
- 企業單一登入(SAML SSO):適用於需要對接企業客戶(如 Okta、Azure AD)的身分驗證系統。
3. 現代化 SSR 開發流程:@supabase/ssr 與 PKCE 流
對於 Next.js, SvelteKit, Nuxt 或 Astro 等伺服器端渲染(SSR)框架,Supabase 已淘汰舊有的 auth-helpers 工具,改由 @supabase/ssr 套件統一處理。
- PKCE 驗證流(Proof Key for Code Exchange):
為了避免存取權杖在瀏覽器端傳遞時被竊取,SSR 環境預設採用 PKCE 流程。使用者點擊驗證連結後,會被引導至您的/auth/callback路由,並攜帶一個臨時的驗證碼(Auth Code)。伺服器收到此驗證碼後,再向 Supabase 交換真正的 Session。 - Cookie 儲存替代 LocalStorage:
單頁應用(SPA)傳統上會將 Session 存於瀏覽器的 LocalStorage 中,但這會導致伺服器端無法讀取。@supabase/ssr會自動將 Session 資訊安全地存在 Cookie 中,以便在前後端之間流暢傳遞。
4. 基礎開發步驟(以 Next.js / React 爲例)
以下為使用 @supabase/ssr 的標準整合配置:
步驟一:安裝套件
npm install @supabase/supabase-js @supabase/ssr
步驟二:建立 Server 端的 Supabase 實例
在 Server 端(例如 Next.js Route Handler 或 Server Action),需要手動處理 Cookie 的讀取與寫入:
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export function createClient() {
const cookieStore = cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// 在某些 Server Component 情境下,若不允許直接寫入 Cookie 可安全忽略
}
},
},
}
)
}
步驟三:實作驗證回呼(Callback)
建立 app/auth/callback/route.ts 路由,用來處理 PKCE 流程中的臨時代碼交換:
import { NextResponse } from 'next/server'
import { createClient } from '@/utils/supabase/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 = createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
return NextResponse.redirect(`${origin}${next}`)
}
}
// 若交換失敗,重導向至錯誤頁面
return NextResponse.redirect(`${origin}/auth/auth-error`)
}
5. 上線生產環境(Production)必備核對清單 (Checklist)
- 啟用資料列級安全性(RLS):
確保所有新建立的資料庫資料表均已啟用 RLS。否則在預設情況下,任何人都可以繞過身分驗證,直接讀寫您的 Postgres 資料庫。 - 設定自訂 SMTP 伺服器:
Supabase 內建的測試用郵件發送限制為每小時 3 封。在生產環境中,您必須配置自訂的 SMTP 服務(如 Resend、Mailgun、SendGrid 等),以防止使用者無法正常收到註冊、忘記密碼或 OTP 信件。 - 配置合法的重導向 URL (Redirect URLs):
請在 Supabase 後台Authentication -> URL Configuration中設定合法的網域(例如您的正式環境網域https://your-domain.com)。未被列入白名單的網域將會被拒絕進行 OAuth 或 Magic Link 的跳轉。 - 管理 API 密鑰安全:
Supabase 採行新型的 API 密鑰模型,原有的 JWT-basedanon和service_role正在逐步替換為可撤銷、可稽核的秘密密鑰(Secret Keys)。請務必避免將service_role金鑰上傳至公開代碼庫,若不慎洩漏,Supabase 支援自動撤銷功能。 - 設置身分驗證鉤子(Auth Hooks):
如果需要實作自訂的驗證邏輯(例如禁止特定網域的 Email 註冊,或是在核發 JWT 前加入自訂欄位),可以利用 PostgreSQL 函數(SQL Functions)並掛載至 Auth Hooks。
這套身分驗證架構兼顧了低維護成本、高自主性與擴充彈性,是替代付費身分驗證服務的常見選擇。