在上一篇文章中,我們學會了 Supabase Auth 的基本使用方式。但要打造一個真正適合生產環境的應用程式,還需要了解更多進階設定。
雖然 Supabase Auth 的預設設定已經相當安全且實用,但每個應用程式都有其獨特的需求:
包括一般設定、密碼安全性、速率限制,以及當遇到問題時該如何除錯。這些知識將幫助你建立更安全、更穩定、更符合實際需求的身份驗證系統。
就像買了一台新車,除了會開車之外,還需要知道如何調整座椅、設定導航、了解各種安全功能。
魔力波長的強弱:直接反映了該個體的實力等級。一個 S 級獵人的魔力波長,會比 E 級獵人的波長來得更強烈、更具壓迫感。
網站 URL 是 Supabase Auth 用來產生確認連結、密碼重設連結等的基礎網址。正確設定網站 URL 對於郵件確認和重導向功能至關重要。
就像你家的地址,當郵差(Supabase)要寄確認信或重設密碼連結給用戶時,需要知道要寄到哪裡。
// 在 Supabase Dashboard 中設定
// Authentication > URL Configuration
// Site URL: https://yourdomain.com
// Redirect URLs:
// - https://yourdomain.com/auth/callback
// - http://localhost:3000/auth/callback (開發環境)
// 在 Supabase Dashboard 中可以設定的會話選項:
// Project Settings > JWT Keys
// JWT expiry (JWT 過期時間)
// 預設:3600 秒 (1 小時)
// 建議:根據應用程式安全需求調整,一般為 1-24 小時
Google 是最常用的社交登入提供者之一。
已授權的 JavaScript 來源:
http://localhost:54321
已授權的重新導向 URI:
http://127.0.0.1:54321/auth/v1/callback
http://localhost:54321/auth/v1/callback
https://your-project.supabase.co/auth/v1/callback (生產環境)
在 .env.local
文件中添加:
# Supabase 配置
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
# Google OAuth 憑證
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
在 supabase/config.toml
中添加:
[auth]
enabled = true
site_url = "http://localhost:3000"
additional_redirect_urls = ["http://127.0.0.1:3000", "http://localhost:3000"]
[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_CLIENT_SECRET)"
redirect_uri = ""
skip_nonce_check = true
在 Supabase Dashboard > Authentication > Sign In / Providers > Google 設定參數:
若在 config.toml
中添加,則不需要在 Supabase Dashboard 中設定。
Supabase Dashboard 設定會自動,將 Client ID 和 Client Secret 輸入到 Supabase 的設定中。
// 設定的參數:
// Client ID (從 Google Cloud Console 取得)
// Client Secret (從 Google Cloud Console 取得)
async function signInWithGoogle() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: 'https://yourdomain.com/auth/callback'
}
})
if (error) {
console.error('Google 登入失敗:', error.message)
}
}
async function signInWithGoogleAdvanced() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
// 重導向 URL - 登入成功後的重導向位置
redirectTo: 'https://yourdomain.com/auth/callback',
// OAuth 範圍 (Scopes) - 定義應用程式需要存取的 Google 服務
scopes: 'openid email profile',
// 查詢參數 - 控制 Google OAuth 流程的行為
queryParams: {
// 提示類型 - 控制用戶互動方式 (如: 是否顯示帳號選擇畫面)
prompt: 'select_account', // 'none' | 'consent' | 'select_account'
// 存取類型 - 決定是否取得 refresh token
access_type: 'offline', // 'online' | 'offline'
// 包含已授權的範圍 - 累積權限
include_granted_scopes: 'true', // 'true' | 'false'
// 語言設定 - 設定 Google OAuth 介面語言
hl: 'zh-TW', // 語言代碼 (如: 'en', 'zh-CN', 'ja')
// 回應類型 - OAuth 2.0 回應類型
response_type: 'code', // 'code' | 'token'
},
}
})
if (error) {
console.error('Google 登入失敗:', error.message)
return { success: false, error }
}
return { success: true, data }
}
建立 app/auth/callback/page.tsx
來處理 OAuth 回調。
export default function AuthCallback() {
const router = useRouter()
useEffect(() => {
const handleCallback = async () => {
const { error } = await supabase.auth.exchangeCodeForSession(
new URLSearchParams(window.location.search).get('code') || ''
)
router.push(error ? '/auth/login?error=callback_failed' : '/auth/success-page')
}
handleCallback()
}, [router])
return (
<div className="flex min-h-screen items-center justify-center">
<div className="animate-spin h-8 w-8 border-2 border-blue-500 border-t-transparent rounded-full" />
</div>
)
}
Supabase Auth 提供多種密碼安全性設定,包括最小長度、複雜度要求等,以確保用戶帳號的安全性。
就像設定家裡的門鎖,你可以選擇簡單的彈簧鎖或複雜的電子鎖,密碼政策就是決定「鎖的複雜程度」。
在 Supabase Dashboard 的 Authentication > Sign In / Providers > Auth Providers > Email 設定:
Minimum password length (最小密碼長度)
Password Requirements (密碼要求)
Email OTP Expiration (電子郵件 OTP 過期時間)
Email OTP Length (電子郵件 OTP 長度)
速率限制是一種防護機制,限制特定時間內來自同一 IP 位址或用戶的請求數量,防止暴力破解攻擊、垃圾註冊等惡意行為。
就像銀行的提款機會限制你一天內的提款次數,速率限制確保沒有人能夠無限制地嘗試登入或註冊,保護系統不被濫用。
這些限制是基於 IP 位址計算的。
在 Supabase Dashboard > Authentication > Rate Limits 中可以調整:
Rate limit for sending emails (郵件發送限制)
Rate limit for sending SMS messages (簡訊發送限制)
Rate limit for token refreshes (權杖刷新限制)
Rate limit for token verifications (權杖驗證限制)
Rate limit for anonymous users (匿名用戶限制)
Rate limit for sign ups and sign ins (註冊和登入限制)
Rate limit for Web3 sign up and sign-in (Web3 登入限制)
Supabase Auth 提供詳細的錯誤碼和訊息,幫助開發者快速識別和解決問題。了解這些錯誤碼對於建立穩健的錯誤處理機制至關重要。
就像醫生看病時的診斷代碼,每個錯誤都有特定的「症狀編號」,讓你能快速找到「病因」和「治療方法」。
{
// 身份驗證錯誤
'invalid_credentials': {
message: '電子郵件或密碼錯誤',
action: 'CHECK_CREDENTIALS',
userMessage: '請檢查您的電子郵件和密碼是否正確'
},
// 用戶相關錯誤
'user_not_found': {
message: '找不到該用戶',
action: 'REDIRECT_TO_SIGNUP',
userMessage: '此電子郵件尚未註冊,請先註冊帳號'
},
'user_already_registered': {
message: '用戶已經註冊',
action: 'REDIRECT_TO_SIGNIN',
userMessage: '此電子郵件已經註冊,請直接登入'
},
// 會話相關錯誤
'session_not_found': {
message: '會話已過期',
action: 'REDIRECT_TO_LOGIN',
userMessage: '登入已過期,請重新登入'
},
'refresh_token_not_found': {
message: '刷新權杖遺失',
action: 'FORCE_LOGOUT',
userMessage: '登入狀態異常,請重新登入'
},
// 速率限制錯誤
'over_email_send_rate_limit': {
message: '郵件發送頻率超限',
action: 'SHOW_RETRY_TIMER',
userMessage: '郵件發送過於頻繁,請稍後再試'
},
'over_sms_send_rate_limit': {
message: '簡訊發送頻率超限',
action: 'SHOW_RETRY_TIMER',
userMessage: '簡訊發送過於頻繁,請稍後再試'
},
// 驗證相關錯誤
'email_not_confirmed': {
message: '電子郵件尚未確認',
action: 'RESEND_CONFIRMATION',
userMessage: '請先確認您的電子郵件'
},
'invalid_token': {
message: '無效的權杖',
action: 'REQUEST_NEW_TOKEN',
userMessage: '驗證連結已過期或無效,請重新申請'
},
// 密碼相關錯誤
'weak_password': {
message: '密碼強度不足',
action: 'SHOW_PASSWORD_REQUIREMENTS',
userMessage: '密碼需要包含大小寫字母、數字和特殊符號'
},
'password_too_short': {
message: '密碼長度不足',
action: 'SHOW_PASSWORD_REQUIREMENTS',
userMessage: '密碼長度至少需要 8 個字元'
}
}
透過適當的配置,可以建立一個真正適合生產環境的身份驗證系統。
... to be continued
有任何想討論歡迎留言,或需要指正的地方請鞭大力一點,歡迎訂閱、按讚加分享,分享給想要提升開發效率的朋友