GCP OAuth Google Sign-In Cloudflare Access 密碼保護 5 個坑

想給網站加認證?別用 Google OAuth

Thomas 花了兩小時嘗試 Google Sign-In,最後發現簡單密碼才是正解。完整踩坑紀錄 + AI Agent 的時間都浪費在哪。

背景:為什麼需要認證?

Thomas 有一堆部署在 Cloudflare Pages 的靜態網站,有些包含私人資料(稅務報告、訓練計劃)。需要一個簡單的方式阻止隨便的人打開。

最初的想法是:用 Google 帳號登入,只允許 thomastangnz@gmail.com 進入。聽起來很高級,對吧?

劇透:最終方案

最終放棄 Google OAuth,改用 HTML 密碼輸入框 + localStorage 30天記住。簡單、零依賴、零配置、零外部服務。

坑 1:gcloud 建不了 OAuth Client ID 浪費 40 分鐘

踩坑:嘗試用命令建立 OAuth Client

Google Sign-In 需要一個 OAuth 2.0 Client ID(Web Application 類型)。直覺想法:用 gcloud 一行命令搞定。

AI Agent 嘗試了 6+ 個 REST API endpoint,全部失敗:

嘗試的方法結果
gcloud iam oauth-clients create --client-type=WEB_CLIENTWEB_CLIENT 不是合法選項(這命令是給 Workforce Identity 用的)
oauth2.googleapis.com/v1/projects/.../oauthClients404 Not Found
clientauthconfig.googleapis.com/v1/...404 Not Found
oauthconfig.googleapis.com/v1/...404 Not Found
iap.googleapis.com/v1/projects/.../brands400: Project must belong to an organization
apikeys.googleapis.com/v2/...空結果(這是 API Key,不是 OAuth)
結論

Google 不提供公開 API 建立標準 OAuth 2.0 Client ID。只能用 Google Cloud Console 網頁手動建立,或用桌面自動化(Playwright)操作 Console。

教訓

當你發現自己嘗試了第 3 個 API endpoint 還是失敗,應該停下來搜尋「能不能用 API 做這件事」,而不是繼續猜 endpoint。有些 Google 服務就是只有 Console UI。

坑 2:桌面自動化太慢 浪費 20 分鐘

踩坑:用 Playwright 操作 GCP Console

API 不行,那就用 AI Agent 的桌面自動化功能(Playwright + Chrome Debug Port)操作 Console。結果:

教訓

Console UI 操作(只需要點 3-5 下的事)讓人手動做永遠比桌面自動化快。Playwright 適合重複性高、步驟多的操作,不適合一次性的簡單配置。

坑 3:OAuth Consent Screen 預設 Testing 模式

踩坑:建好了 Client ID,登入卻報 401

好不容易建好了 OAuth Client ID,部署了帶 Google Sign-In 的網頁。點擊登入按鈕,看到:

禁止访问:发生了授权错误
The OAuth client was not found.
Error 401: invalid_client

Client ID 明明存在(Console 上能看到),為什麼 Google 說找不到?

原因:Consent Screen 還在 Testing 模式

GCP 建立 OAuth Consent Screen 時,預設是 Testing 狀態。在這個狀態下:

修法:去 GCP Console → APIs & Services → OAuth consent screen → 點 PUBLISH APP,或者手動加入你的 email 作為 Test User。

手動操作步驟(小白版)

  1. 打開瀏覽器,前往 console.cloud.google.com
  2. 左上角選你的 GCP 項目(如 nvda-strategy)
  3. 左邊選單:APIs & Services → OAuth consent screen
  4. 看 Publishing status:
    • 如果顯示 Testing → 點 PUBLISH APP → 確認
    • 或者在 Test users 區塊點 + ADD USERS → 輸入你的 Gmail → Save
  5. 回到你的網站試試看

坑 4:Cloudflare Access 擋在 HTML 前面

踩坑:部署了密碼保護,但用戶根本看不到

有些網站之前用 Cloudflare Access(Zero Trust)保護。即使部署了新的帶密碼的 HTML,用戶打開網址看到的還是 Cloudflare 的登入頁(那個顯示 Google OAuth 錯誤的頁面)。

原因:Cloudflare Access 在 CDN 層攔截請求,優先級高於你的 HTML 內容。你的密碼頁面根本沒機會載入。

解法:移除 Cloudflare Access Application

如果改用 HTML 密碼保護,就不再需要 Cloudflare Access。必須手動移除。

移除 Cloudflare Access 的步驟(小白版)

  1. 打開 one.dash.cloudflare.com(Cloudflare Zero Trust Dashboard)
  2. 左邊選單:Access → Applications
  3. 找到你要移除保護的網站(如 triathlon-2026)
  4. 點最右邊的 ...(三個點)→ Delete
  5. 確認刪除
  6. 對每個需要移除的網站重複上面的步驟
  7. 等 1-2 分鐘讓 Cloudflare CDN 生效
  8. 打開網站,應該能看到你的 HTML 密碼輸入框了
為什麼 AI Agent 無法自動移除?

Cloudflare Access(Zero Trust)的 API 需要特殊的 API Token 權限。wrangler 預設的 OAuth Token 只有 Pages/Workers/KV/D1 等權限,沒有 Zero Trust 管理權限。所以只能手動操作 Dashboard。

坑 5:部署後沒測試就交付

踩坑:AI 說「完成了」,實際上登入失敗

AI Agent 完成了三步(建 OAuth Client → 改 HTML → 部署),回報「全部完成」。但用戶打開網站一試,直接報錯。

原因:AI 沒有在部署後打開網站實際測試登入流程。如果測了,就能當場發現 Consent Screen 的問題。

教訓

任何涉及認證/登入的改動,部署後必須實際走一遍完整流程。不是看代碼「應該沒問題」,而是真的打開瀏覽器點一下。

最終方案:HTML 密碼保護

折騰了 Google OAuth 兩小時後,最終方案是最簡單的:一個密碼輸入框

為什麼密碼比 Google OAuth 好(對靜態網站而言)
Google OAuth:需要 GCP 項目 + Consent Screen + Client ID + SDK + JWT 解碼
任何一環出問題(Consent Screen 未發布、Client ID 錯誤)= 整個登入壞掉
HTML 密碼:一段 JavaScript + localStorage
零外部依賴,不可能因為 Google 的配置問題而壞掉

完整代碼模板(複製即用)

<!-- 1. CSS - 加在 <style> 裡 -->
#pw-screen {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  background: #0f172a; z-index: 9999;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 16px;
  font-family: sans-serif;
}
.pw-title { font-size: 1.5rem; font-weight: 700; color: #e2e8f0; }
.pw-sub { color: #94a3b8; font-size: 0.9rem; }
#pw-input {
  padding: 12px 20px; border-radius: 10px;
  border: 1px solid #334155; background: #1e293b;
  color: #e2e8f0; font-size: 1rem; width: 260px;
  text-align: center; outline: none;
}
#pw-input:focus { border-color: #60a5fa; }
#pw-btn {
  padding: 10px 32px; border-radius: 10px; border: none;
  background: #60a5fa; color: #fff; cursor: pointer;
}
#pw-error { display: none; color: #fb7185; font-size: 0.85rem; }

<!-- 2. HTML - 加在 <body> 最前面 -->
<div id="pw-screen">
  <div style="font-size:2.5rem">&#x1F512;</div>
  <div class="pw-title">請輸入密碼</div>
  <div class="pw-sub">此頁面受密碼保護</div>
  <input type="password" id="pw-input" placeholder="請輸入密碼" />
  <button id="pw-btn" onclick="checkPw()">進入 &rarr;</button>
  <div id="pw-error">密碼錯誤,請重試</div>
</div>

<!-- 3. Script - 加在 </body> 前面 -->
<script>
const PW = '你的密碼';
const PW_KEY = location.hostname + '_pw';  // 每個網站獨立 key
const PW_DAYS = 30;

function isPwOk() {
  try {
    const d = JSON.parse(localStorage.getItem(PW_KEY) || '{}');
    return d.ok && Date.now() < d.exp;
  } catch(e) { return false; }
}

function checkPw() {
  if (document.getElementById('pw-input').value === PW) {
    localStorage.setItem(PW_KEY, JSON.stringify({
      ok: 1,
      exp: Date.now() + PW_DAYS * 24 * 60 * 60 * 1000
    }));
    document.getElementById('pw-screen').style.display = 'none';
  } else {
    document.getElementById('pw-error').style.display = 'block';
    document.getElementById('pw-input').value = '';
    document.getElementById('pw-input').focus();
  }
}

// 頁面載入時自動檢查
if (isPwOk()) {
  document.getElementById('pw-screen').style.display = 'none';
}
document.getElementById('pw-input')
  .addEventListener('keydown', e => { if (e.key === 'Enter') checkPw(); });
</script>

認證邏輯流程圖

密碼保護流程
用戶打開網頁
檢查 localStorage 是否有未過期的 token
有 → 隱藏密碼框,直接顯示內容(30天免輸入)
沒有 → 顯示全屏密碼輸入框
用戶輸入密碼 → 按 Enter 或點「進入」
密碼正確 → 存 localStorage + 隱藏密碼框
密碼錯誤 → 顯示紅字提示,清空輸入框

AI Agent 的時間都浪費在哪?

階段花費時間問題
嘗試 6 個 API endpoint 建 OAuth Client~40 分鐘應該第 3 次失敗就停下來確認「這東西有沒有 API」
桌面自動化操作 GCP Console~20 分鐘人手 2 分鐘能搞定的事
部署後沒有測試交付了壞的東西,浪費下一輪時間排查
排查 401 invalid_client 錯誤~15 分鐘如果部署後立刻測試,這 15 分鐘可以省掉
總計浪費:~75 分鐘(人手做完全程只需 10 分鐘)

三種網站認證方案對比

HTML 密碼Google Sign-InCloudflare Access
難度簡單(複製模板)中等(需 GCP 配置)中等(需 CF 配置)
外部依賴GCP 項目 + Consent ScreenCF Zero Trust
安全性低(密碼在前端)
適用場景私人靜態網站需要識別用戶身份企業級保護
壞掉風險極低高(Consent Screen、API 變更)中(Token 權限問題)
AI 可自動化完全可以部分需手動部分需手動
什麼時候才需要 Google OAuth?

當你需要識別用戶身份(不只是擋住陌生人)的時候。例如:多用戶系統、不同用戶看到不同內容、記錄誰做了什麼操作。如果只是「不想讓隨便的人看到」,HTML 密碼就夠了。

總結:5 個教訓

下次記住這些

  1. 選最簡單的方案 —— 「能不能用密碼」永遠是第一個問題,別一上來就 OAuth
  2. GCP OAuth Client 只能在 Console 建 —— 別浪費時間找 API
  3. Consent Screen 預設 Testing —— 建完 Client 後一定要 Publish 或加 Test User
  4. Cloudflare Access 攔截優先於 HTML —— 換了認證方式要記得移除舊的 Access Policy
  5. 認證改動必須實測 —— 部署後打開瀏覽器走一遍完整流程再交付