🔑

Google OAuth 全家桶授權指南

從零開始配置 Google API 授權,一次搞定 22 個 API Scope,解決品牌驗證、Photos API 限制等常見問題

Google API OAuth 2.0 GCP / Cloudflare 已完成

📑 目錄

  1. 前言:為什麼需要 Google OAuth
  2. 準備工作:GCP 項目設置
  3. OAuth 同意畫面設置(重要坑點)
  4. 執行授權流程
  5. 測試所有 API 連接
  6. Google Photos API 的特殊限制
  7. 品牌驗證流程(如果你需要 Photos API)
  8. 多台電腦共享 Token
  9. FAQ 常見問題
Part 1

前言:為什麼需要 Google OAuth

什麼是 OAuth?

如果你跟我一樣,想讓自己的程式自動上傳 YouTube 影片、讀取 Gmail 信件、管理 Google Calendar、操作 Google Drive 裡的檔案,你就需要 OAuth 2.0 授權

💡 比喻:酒店房卡 vs 萬能鑰匙

想像你住飯店。OAuth 就像是飯店給你的房卡 — 它只能打開你的房間,不能打開其他房間,也不能進入員工區域。你不需要把飯店的萬能鑰匙(你的 Google 密碼)交給任何人。程式拿到的是一張有限制的房卡(Token),只能存取你授權的功能。

為什麼需要它?

Google 不允許程式直接用你的帳號密碼登入(這太危險了)。取而代之的是一套標準流程:

  1. 你的程式向 Google 說:「我想存取這個用戶的 YouTube 和 Gmail」
  2. Google 跳出一個授權頁面,問你:「你同意讓這個程式存取嗎?」
  3. 你點「同意」後,Google 發給程式一個 Token(通行證)
  4. 程式拿著這個 Token 就可以代替你操作 Google 服務

最終目標

完成這份指南後,你將擁有一組 Token 可以存取 22 個 Google API Scope,包括:YouTube、Drive、Gmail、Calendar、Sheets、Docs、Slides、Photos、Tasks、Contacts。一次授權,全部搞定。

ℹ️ 適用對象

這份指南寫給完全沒接觸過 Google API 的新手。每一步都會詳細解釋,不會跳過任何細節。即使你只是想操作自己的 Google 帳號(個人用途),也需要完成這些設置。

Part 2

準備工作:GCP 項目設置

Step 1:建立 GCP 專案

  1. 前往 Google Cloud Console
  2. 點擊頂部的專案選擇器,選擇 新增專案 (New Project)
  3. 輸入專案名稱,例如 nvda-strategy(用你自己的名稱即可)
  4. 點擊 建立 (Create)

Step 2:啟用需要的 API

在左側選單進入 API 和服務 (APIs & Services)程式庫 (Library),搜尋並逐一啟用以下 API:

API 名稱用途
YouTube Data API v3上傳影片、管理頻道、讀取播放清單
Google Drive API上傳下載檔案、管理資料夾
Gmail API讀取發送郵件
Google Calendar API讀寫日曆事件
Google Sheets API讀寫試算表
Google Docs API讀寫文件
Google Slides API讀寫簡報
Photos Library API上傳照片、管理相簿
Tasks API讀寫待辦事項
People API (Contacts)讀取聯絡人資訊
✅ 小提示

一次把所有 API 都啟用,之後就不用重複來這邊了。啟用 API 不收費,只有實際呼叫超過免費額度才需要付費(個人用途幾乎不可能超過)。

Step 3:建立 OAuth 同意畫面

  1. 進入 API 和服務OAuth 同意畫面 (OAuth consent screen)
  2. 選擇 外部 (External) 類型(即使你只給自己用,也要選 External)
  3. 填寫應用程式名稱(注意:不能包含 Google 產品名稱,詳見 Part 3)
  4. 填寫支援電子郵件、開發者聯絡資訊
  5. 在 Scopes 頁面加入你需要的權限(稍後 Part 4 會列出完整清單)

Step 4:建立 OAuth Client ID

  1. 進入 API 和服務憑證 (Credentials)
  2. 點擊 建立憑證 (Create Credentials)OAuth 用戶端 ID (OAuth Client ID)
  3. 應用程式類型選擇 桌面應用程式 (Desktop app)
  4. 點擊 建立
  5. 下載 JSON 檔案,儲存為 client_secret.json
🚨 安全提醒

client_secret.json 是你的應用程式憑證,絕對不要上傳到 GitHub 或任何公開場所。加入 .gitignore 是最低要求。

Part 3

OAuth 同意畫面設置(重要坑點)

這一章記錄了我踩過的最大的坑。如果你不知道這些,可能會浪費好幾天在找問題。

坑點 1:Testing Mode vs Production Mode

🚨 最大的坑:Testing Mode 下 Token 7 天就過期!

這是整份指南最重要的一點。預設情況下,你的 OAuth 同意畫面是 測試中 (Testing) 模式。

  • Testing 模式:Token 只有 7 天有效期。7 天後你的程式就會突然斷線,所有 API 呼叫都會失敗。你需要重新授權。
  • Production 模式:Token 永久有效(只要你不主動撤銷)。Refresh Token 會自動更新 Access Token。
項目Testing 模式Production 模式
Token 有效期7 天永久
可使用的用戶僅白名單中的測試帳號任何 Google 帳號
授權畫面顯示「此應用未驗證」警告同樣顯示警告(除非通過品牌驗證)
適合場景開發初期測試個人使用、正式上線

操作方法:在 OAuth 同意畫面頁面,找到 發布狀態 (Publishing status),點擊 推送至正式版 (Push to Production)

💡 比喻

Testing 模式像是一張「臨時訪客證」,7 天後自動失效。Production 模式像是一張「正式員工證」,只要你還在公司就一直有效。即使你只是個人使用,也一定要切換到 Production。

坑點 2:應用程式名稱不能包含 Google 產品名

你可能會很自然地把應用取名為「YouTube Uploader」或「Gmail Manager」。千萬別這樣做。

Google 會在品牌驗證時拒絕包含其產品名稱的應用名。這是他們的品牌保護政策。

名稱結果
YouTube Uploader被拒絕
Gmail Manager被拒絕
Google Drive Tool被拒絕
TT Personal Tools通過
My Automation Hub通過
✅ 建議

使用一個通用的、不包含任何 Google 品牌名的應用名稱,例如 TT Personal Tools。簡短、安全、不會被拒。

Part 4

執行授權流程

準備工作做完了,現在來實際執行授權,拿到那張「萬能房卡」(Token)。

安裝必要的 Python 套件

# 安裝 Google Auth 相關套件
pip install google-auth google-auth-oauthlib google-auth-httplib2
pip install google-api-python-clientbash

完整的 22 個 Scope

以下是我一次性授權的所有 Scope。你可以根據自己的需求刪減,但建議全部加上 — 反正授權一次就好。

SCOPES = [
    # YouTube
    "https://www.googleapis.com/auth/youtube",
    "https://www.googleapis.com/auth/youtube.upload",
    "https://www.googleapis.com/auth/youtube.readonly",
    "https://www.googleapis.com/auth/youtube.force-ssl",
    # Gmail
    "https://www.googleapis.com/auth/gmail.modify",
    "https://www.googleapis.com/auth/gmail.send",
    "https://www.googleapis.com/auth/gmail.readonly",
    # Drive
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/drive.file",
    # Calendar
    "https://www.googleapis.com/auth/calendar",
    "https://www.googleapis.com/auth/calendar.events",
    # Sheets, Docs, Slides
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/presentations",
    # Photos
    "https://www.googleapis.com/auth/photoslibrary",
    "https://www.googleapis.com/auth/photoslibrary.readonly",
    "https://www.googleapis.com/auth/photoslibrary.appendonly",
    # Tasks
    "https://www.googleapis.com/auth/tasks",
    # Contacts (People API)
    "https://www.googleapis.com/auth/contacts.readonly",
    "https://www.googleapis.com/auth/contacts",
    # Gmail SMTP (for sending via SMTP)
    "https://mail.google.com/",
    # Profile
    "https://www.googleapis.com/auth/userinfo.email",
]python

授權腳本

import json
from google_auth_oauthlib.flow import InstalledAppFlow

CLIENT_SECRET_FILE = "client_secret.json"
TOKEN_OUTPUT_FILE  = "token.json"

# SCOPES 就是上面那個完整列表
SCOPES = [...]  # 貼上上面的 22 個 scope

def main():
    # 建立授權流程
    flow = InstalledAppFlow.from_client_secrets_file(
        CLIENT_SECRET_FILE,
        scopes=SCOPES
    )

    # 啟動本地伺服器,開啟瀏覽器讓你登入授權
    creds = flow.run_local_server(port=0)

    # 將 Token 保存為 JSON
    token_data = {
        "token": creds.token,
        "refresh_token": creds.refresh_token,
        "token_uri": creds.token_uri,
        "client_id": creds.client_id,
        "client_secret": creds.client_secret,
        "scopes": creds.scopes,
    }
    with open(TOKEN_OUTPUT_FILE, "w") as f:
        json.dump(token_data, f, indent=2)

    print(f"Token saved to {TOKEN_OUTPUT_FILE}")
    print(f"Scopes granted: {len(creds.scopes)}")

if __name__ == "__main__":
    main()python

執行授權

  1. 確保 client_secret.json 在同一目錄下
  2. 執行腳本:python authorize.py
  3. 瀏覽器會自動彈出 Google 登入頁面
  4. 登入你的 Google 帳號
  5. 你會看到「此應用未驗證」警告,點 進階 (Advanced)前往 TT Personal Tools(不安全)
  6. 勾選所有權限,點 繼續 (Continue)
  7. 授權成功!token.json 已生成
💡 比喻

run_local_server 的原理:腳本會在你的電腦上啟動一個臨時的小型 Web 伺服器(就像一個臨時的收件地址)。Google 授權完成後,會把 Token 送到這個地址,然後腳本接收到 Token 就自動關閉伺服器。整個過程全自動,你只需要在瀏覽器點同意就好。

(可選)將 Token 存入 GCP Secret Manager

如果你有多台電腦需要使用同一個 Token,建議存入 GCP Secret Manager,詳見 Part 8

from google.cloud import secretmanager

def store_token_to_secret_manager(project_id, secret_id, token_json_str):
    client = secretmanager.SecretManagerServiceClient()
    parent = f"projects/{project_id}/secrets/{secret_id}"

    response = client.add_secret_version(
        request={
            "parent": parent,
            "payload": {"data": token_json_str.encode("UTF-8")},
        }
    )
    print(f"Stored token version: {response.name}")python
Part 5

測試所有 API 連接

授權完成後,來驗證每個 API 是不是都能正常工作。以下是我的實際測試結果:

#服務狀態備註
1YouTube Data API✅ 通過上傳、讀取播放清單均正常
2Gmail API✅ 通過讀取、發送郵件正常
3Google Drive✅ 通過上傳下載檔案正常
4Google Calendar✅ 通過讀寫事件正常
5Google Sheets✅ 通過讀寫儲存格正常
6Google Docs✅ 通過讀寫文件正常
7Google Slides✅ 通過讀寫簡報正常
8Contacts (People API)✅ 通過讀取聯絡人正常
9Tasks API✅ 通過讀寫待辦事項正常
10Google Photos❌ 失敗403 錯誤 — 需要品牌驗證(詳見 Part 6)
11Gmail SMTP✅ 通過透過 SMTP 發送正常
12QQ Mail SMTP✅ 通過QQ 郵箱轉發正常
13Alpaca Trading API✅ 通過股票交易 API 正常
14Cloudflare API✅ 通過DNS 管理正常
15WinRM✅ 通過Windows 遠端管理正常
16GCP Secret Manager✅ 通過讀寫 Secret 正常
17Tailscale✅ 通過VPN 連線正常

結果:17 / 18 項通過,唯一失敗的是 Google Photos API。這不是你的問題,是 Google 的特殊限制。繼續往下看。

ℹ️ 注意

上表中 #11-17 是非 Google OAuth 的服務,放在一起只是因為我在同一輪測試中驗證了所有 API 連接。Google OAuth Token 負責的是 #1-10 的服務。

Part 6

Google Photos API 的特殊限制

這是所有 Google API 中最特殊的一個,行為跟其他 API 完全不同。

問題:即使授權成功,也會 403

你已經在 OAuth 授權時勾選了 Photos Library 的所有權限,Token 裡也包含了 Photos 的 scope,但當你實際呼叫 Photos API 時,會收到:

HTTP 403 Forbidden
{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED"
  }
}json

原因:Photos API 要求品牌驗證

Google Photos API 有一條特殊規則:未通過品牌驗證的應用,即使 Token 中包含 Photos scope,也不被允許存取。

這跟其他所有 Google API 都不同 — YouTube、Drive、Gmail、Calendar 等,未驗證的應用都可以正常使用(只是授權時會有「此應用未驗證」的警告)。

💡 比喻

大部分 Google 服務就像一般的大樓 — 你有房卡就能進去,大門警衛可能會提醒你「這張卡片沒有照片認證」,但還是會讓你進去。但 Photos API 就像是一棟特殊的政府大樓,不管你有沒有房卡,必須先通過身份驗證才能進入

品牌驗證需要什麼?

如果你不需要 Photos API

✅ 好消息

如果你不需要操作 Google Photos,那完全不需要做品牌驗證。其他 17 個 API 都可以正常使用,不受影響。未驗證的狀態沒有任何負面後果。

如果你需要 Photos API

繼續看 Part 7:品牌驗證流程

Part 7

品牌驗證流程(如果你需要 Photos API)

這個流程比較繁瑣,但只需要做一次。以下是完整的步驟和我踩過的每一個坑。

Step 1:建立隱私權政策網頁

Google 要求你的應用有一個公開的隱私權政策頁面。最簡單的方式是部署到 Cloudflare Pages。

  1. 建立一個簡單的 HTML 隱私權政策頁面(網上有很多模板)
  2. 部署到 Cloudflare Pages(免費方案就夠了)
  3. 確保可以從公開網路存取,例如 https://privacy.yourdomain.com
🚨 坑點:首頁和隱私權政策必須是不同的 URL

Google 要求你填寫應用程式首頁隱私權政策頁面兩個不同的 URL。它們不能是同一個網址!例如:

  • 首頁:https://yourdomain.com
  • 隱私權政策:https://yourdomain.com/privacy

而且首頁必須有一個連結指向隱私權政策頁面。

Step 2:在 Google Search Console 驗證網域

  1. 前往 Google Search Console
  2. 新增資源,選擇 網址前置字元 (URL prefix) 類型
  3. 輸入你的網域(例如 https://yourdomain.com
  4. 選擇 HTML 標記 (HTML tag) 驗證方式
  5. 複製 Google 給你的 <meta> 標籤,加到你網站的 <head>
  6. 重新部署網站,然後回到 Search Console 點擊 驗證 (Verify)
<!-- 加在你首頁的 <head> 中 -->
<meta name="google-site-verification"
      content="你的驗證碼" />html
🚨 坑點:必須先驗證網域

在 OAuth 同意畫面填寫網域之前,必須先在 Search Console 完成驗證。如果你先填了網域再去驗證,可能會遇到「無法驗證網域擁有權」的錯誤。順序很重要!

Step 3:填寫 OAuth 同意畫面品牌資訊

  1. 回到 GCP Console → API 和服務OAuth 同意畫面
  2. 填寫 應用程式名稱(記住不能包含 Google 產品名)
  3. 填寫 應用程式首頁 URL
  4. 填寫 隱私權政策連結 URL
  5. 填寫 授權網域 (Authorized domains)

Step 4:提交驗證申請

  1. 在同意畫面頁面,點擊 提交驗證 (Submit for verification)
  2. 填寫每個 scope 的使用說明(用英文)
  3. 上傳應用程式的示範影片(錄製你的程式如何使用這些 API)
  4. 提交,等待 Google 審核
🚨 坑點:示範影片不能跳過

Google 要求你錄製一段影片,展示你的應用如何使用所申請的 scope。這不是可選的,是必須的。影片不需要很精美,只需要用螢幕錄製工具展示你的程式如何操作 Google Photos 就行。上傳到 YouTube(不公開)即可。

等待審核期間

✅ 好消息:可以一直掛著驗證申請

提交驗證後,你的應用會顯示「驗證待處理」狀態。這個狀態沒有任何負面後果

  • 其他 17 個 API 完全不受影響,繼續正常使用
  • 你的應用不會被停用
  • 沒有時間限制,可以無限期掛著
  • Google 不會因為你一直掛著而拒絕你

所以如果你不急著用 Photos API,可以先提交驗證,然後慢慢等。

踩坑總結

坑點解法
首頁和隱私權政策是同一個 URL分開為兩個 URL,首頁加連結到 privacy 頁面
應用名包含 Google 產品名改用 TT Personal Tools 等中性名稱
填寫網域前沒在 Search Console 驗證先在 Search Console 驗證,再回來填寫
沒有示範影片用螢幕錄製工具錄一段,上傳 YouTube
擔心一直掛著驗證會被拒不會,可以放心掛著,無負面後果
Part 8

多台電腦共享 Token

如果你跟我一樣有桌機和筆電,想兩台電腦都能呼叫 Google API,怎麼辦?答案是用 GCP Secret Manager 來集中存放 Token。

💡 比喻

想像你的 Token 是一把鑰匙。與其每台電腦各配一把(每台都要重新授權),不如把鑰匙放在一個安全的保險箱裡(Secret Manager),每台電腦需要用的時候去保險箱拿最新的那把就好。

架構

  ┌──────────────┐          ┌───────────────────┐
  │   Desktop    │ ───────▶ │                   │
  │  (主要授權)   │ ◀─────── │   GCP Secret      │
  └──────────────┘  讀/寫    │   Manager         │
                             │                   │
  ┌──────────────┐          │  token.json       │
  │   Laptop     │ ───────▶ │  (最新版本)        │
  │  (次要讀取)   │ ◀─────── │                   │
  └──────────────┘  讀取     └───────────────────┘diagram

讀取 Token

from google.cloud import secretmanager
import json

def get_token_from_secret_manager(project_id, secret_id):
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{project_id}/secrets/{secret_id}/versions/latest"

    response = client.access_secret_version(request={"name": name})
    token_data = json.loads(response.payload.data.decode("UTF-8"))

    return token_datapython

自動更新流程

  1. 程式啟動時,從 GCP Secret Manager 讀取最新的 token.json
  2. 使用 Token 呼叫 Google API
  3. 如果 Access Token 過期,用 Refresh Token 自動更新
  4. 更新後,把新的 Token 寫回 GCP Secret Manager
  5. 其他電腦下次啟動時,就會拿到最新的 Token
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request

def load_and_refresh_token(project_id, secret_id):
    # 1. 從 Secret Manager 讀取
    token_data = get_token_from_secret_manager(project_id, secret_id)

    # 2. 建立 Credentials 物件
    creds = Credentials(
        token=token_data["token"],
        refresh_token=token_data["refresh_token"],
        token_uri=token_data["token_uri"],
        client_id=token_data["client_id"],
        client_secret=token_data["client_secret"],
    )

    # 3. 自動刷新過期的 Token
    if creds.expired:
        creds.refresh(Request())
        # 4. 寫回 Secret Manager
        new_token = json.dumps({
            "token": creds.token,
            "refresh_token": creds.refresh_token,
            "token_uri": creds.token_uri,
            "client_id": creds.client_id,
            "client_secret": creds.client_secret,
        })
        store_token_to_secret_manager(project_id, secret_id, new_token)

    return credspython
✅ 小提示

GCP Secret Manager 的免費額度非常大(每月 10,000 次存取),個人用途完全免費。而且它的存取控制比把 Token 放在 Google Drive 安全得多。

Part 9

FAQ 常見問題

Q: Token 會過期嗎?
Production 模式下不會。Access Token 每小時過期一次,但 Refresh Token 會自動換取新的 Access Token,你不需要重新授權。只要你不主動撤銷,Token 永久有效。但如果你是 Testing 模式,Refresh Token 7 天後就會失效,所以一定要切換到 Production。
Q: 未驗證品牌有什麼影響?
影響很小。授權時會有一個「此應用未驗證」的安全警告頁面,你需要手動點「進階 → 繼續前往」才能授權。除此之外,Google Photos API 會被封鎖(403),但其他所有 API(YouTube、Drive、Gmail、Calendar 等)都完全正常。
Q: 可以一直掛著驗證申請嗎?
可以,完全沒有負面後果。提交品牌驗證後,你的應用會進入「待審核」狀態。這不會影響你現有的功能,其他 API 繼續正常使用。Google 不會因為你長期不回覆而停用你的應用。
Q: 需要錄示範影片嗎?
只有需要 Photos API 時才要。如果你提交品牌驗證(為了解鎖 Photos API),Google 會要求你提供一段示範影片。如果你不需要 Photos API,完全不需要做品牌驗證,當然也不需要錄影片。
Q: Testing vs Production 最大區別?
Token 有效期:7 天 vs 永久。這是唯一真正重要的區別。Testing 模式下 Refresh Token 7 天過期,程式會突然斷線。Production 模式下 Token 永久有效。其他差異(如測試帳號限制)對個人用途來說都不重要。
Q: 一個 Token 可以用多少個 API?
理論上不限。Token 的權限由 scope 決定。你在授權時申請多少 scope,Token 就有多少權限。本指南的做法是一次授權 22 個 scope,一個 Token 走天下。
Q: 可以在伺服器上跑嗎?
可以。先在有瀏覽器的電腦上完成授權(拿到 token.json),然後把 Token 存到 GCP Secret Manager,伺服器從 Secret Manager 讀取即可。伺服器本身不需要瀏覽器。
P1 前言 P2 GCP P3 坑點 P4 授權 P5 測試 P6 Photos P7 驗證 P8 共享 P9 FAQ ↑ 回到頂部