diff --git a/deploy/github-supabase-deploy.md b/deploy/github-supabase-deploy.md index 77b79e5..11e0422 100644 --- a/deploy/github-supabase-deploy.md +++ b/deploy/github-supabase-deploy.md @@ -1,5 +1,7 @@ # GitHub Pages + Supabase 部署 +> ⚠️ **重建前必讀(2026-10-31,SEC-P1-20261031)**:`.github.io` 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個 Pages 站的腳本都讀得到這個 origin 的 localStorage,而 Supabase Auth 會把登入 session 存在 localStorage。因此前端在 `*.github.io` 上時會**自動停用 Google 登入**。重建線上服務時,前端改放在獨立網域(例如 Cloudflare Pages 的 `*.pages.dev`,免費),下文的 Authorized JavaScript origins、Site URL 與 `CORS_ORIGINS` 都改填該網域。 + 正式環境不使用 Render。GitHub Pages 發布前端,Supabase Edge Function 提供 API,Supabase Database 保存資料。 ## 架構 diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 379bc9b..5ba52b5 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -19,7 +19,12 @@ const ONLINE_API_RETIRED = !API_BASE; const ONLINE_API_RETIRED_MESSAGE = "線上 API 已停用,請在本機啟動 FastAPI 練習。"; const SUPABASE_URL = String(import.meta.env.VITE_SUPABASE_URL || "").trim(); const SUPABASE_PUBLISHABLE_KEY = String(import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY || "").trim(); -const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY +// *.github.io 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個站的腳本都讀得到這裡的 +// localStorage。Supabase 會把登入 session 存在 localStorage,所以在共用 origin 上一律不啟用登入; +// 重建線上服務時,前端要放在獨立網域(見 deploy/github-supabase-deploy.md)。 +const SHARED_PAGES_ORIGIN = window.location.hostname.endsWith(".github.io"); +const AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE = "這個網址與其他 GitHub Pages 網站共用,為保護登入狀態已停用 Google 登入。"; +const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && !SHARED_PAGES_ORIGIN ? createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, { auth: { autoRefreshToken: true, detectSessionInUrl: true, persistSession: true }, }) @@ -89,7 +94,7 @@ function AccountMenu({ if (!authClientConfigured) { return (
- Google 登入尚未設定 + {SHARED_PAGES_ORIGIN ? AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE : "Google 登入尚未設定"}
); } @@ -664,7 +669,7 @@ function App() { const handleSignIn = useCallback(async () => { if (!authClient) { - showBanner("Google 登入尚未設定。", true); + showBanner(SHARED_PAGES_ORIGIN ? AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE : "Google 登入尚未設定。", true); return; } setIsSigningIn(true); diff --git a/static/js/learn.js b/static/js/learn.js index 23b0b7c..e2684b6 100644 --- a/static/js/learn.js +++ b/static/js/learn.js @@ -6,7 +6,12 @@ const API_DOCS_URL = "https://github.com/frobel0520/AI-Agent-Tutorial/tree/main/ const OWN_WEBHOOK_PATH = "/hooks/incoming"; const SUPABASE_URL = String(window.APP_CONFIG?.supabaseUrl || "").trim(); const SUPABASE_PUBLISHABLE_KEY = String(window.APP_CONFIG?.supabasePublishableKey || "").trim(); -const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && window.supabase?.createClient +// *.github.io 是同一帳號所有 GitHub Pages 專案共用的 origin,任何一個站的腳本都讀得到這裡的 +// localStorage。Supabase 會把登入 session 存在 localStorage,所以在共用 origin 上一律不啟用登入; +// 重建線上服務時,前端要放在獨立網域(見 deploy/github-supabase-deploy.md)。 +const SHARED_PAGES_ORIGIN = window.location.hostname.endsWith(".github.io"); +const AUTH_DISABLED_ON_SHARED_ORIGIN_MESSAGE = "這個網址與其他 GitHub Pages 網站共用,為保護登入狀態已停用 Google 登入。"; +const authClient = SUPABASE_URL && SUPABASE_PUBLISHABLE_KEY && !SHARED_PAGES_ORIGIN && window.supabase?.createClient ? window.supabase.createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, { auth: { autoRefreshToken: true, detectSessionInUrl: true, persistSession: true }, })