如果你想把 Cloudflare 的流量、防火牆事件或網站請求資料拉進自己的報表,第一步不是使用 Global API Key,而是建立一組權限受限的 Cloudflare API Token。這篇會從後台建立 Token 開始,實際串接 GraphQL Analytics API,並把最常見的 401、403 與查詢錯誤一次說清楚。
先講重點:API Token 就像交給程式使用的一張門禁卡。它應該只能讀取指定帳號、指定網域與指定資料,不要為了省幾分鐘設定,就把整個 Cloudflare 帳號的權限全部交出去。
Cloudflare API Token 是什麼?
Cloudflare API Token 是讓程式、CLI、監控工具或自動化流程呼叫 Cloudflare API 的驗證憑證。和早期的 Global API Key 相比,Token 可以限制權限、資源、來源 IP 與有效期限,因此 Cloudflare 也把 API Token 列為建議的驗證方式。
| 比較項目 | API Token | Global API Key |
|---|---|---|
| 權限範圍 | 可限制為 Read 或特定功能 | 權限範圍很大 |
| 網域限制 | 可限定單一 Zone | 跟著帳號權限走 |
| 來源限制 | 可限制 IP | 較難細分 |
| 有效期限 | 可設定 TTL | 通常長期有效 |
| 適合用途 | 正式串接與自動化 | 相容舊系統 |
如果你之前做過 LINE Messaging API Access Token,觀念其實很像:程式不是拿你的帳號密碼登入,而是帶著一組可以被撤銷、限制用途的 Token 呼叫服務。
GraphQL Analytics API 可以拿來做什麼?
Cloudflare GraphQL Analytics API 可以讓我們用查詢語法挑選需要的分析資料,而不是每次下載一大包固定格式的結果。常見用途包括:
- 統計網站請求量與資料傳輸量。
- 分析來源國家、裝置、網址路徑與回應狀態。
- 查詢 WAF、防火牆與 Cloudflare Access 事件。
- 把 Cloudflare 數據匯入 Grafana、Looker Studio 或自製報表。
- 讓 AI Agent 或維運腳本定期檢查異常流量。
Cloudflare 目前的 GraphQL 端點是 https://api.cloudflare.com/client/v4/graphql,請求使用 HTTP POST,驗證則放在 Authorization: Bearer Header。
建立 Cloudflare Analytics API Token
步驟一:進入 API Tokens
登入 Cloudflare 後台,進入帳號的 API Tokens 頁面,點選 Create Token。這次不要套用 DNS 編輯範本,而是找到 Custom token,再點選 Get started。
Token 名稱建議直接寫出用途,例如:
iambigd-cloudflare-analytics-read
不要只命名為 test、api 或 token。半年後需要停用時,清楚的名稱可以避免誤刪正在運作的服務。
步驟二:設定最小讀取權限
依照 Cloudflare Analytics 官方文件,權限選擇:
- 第一欄:Account
- 第二欄:Account Analytics
- 第三欄:Read
這組 Token 是拿來讀分析資料,所以不要選 Edit。能用 Read 完成的工作,就不要多給修改權限。
步驟三:限制可存取的網域
在 Zone Resources 選擇要開放的網域。測試時雖然可以選 All zones,但正式使用建議指定單一 Zone,例如只允許讀取 iambigd.tw。
如果這組 Token 需要由固定伺服器使用,可以再設定 Client IP Address Filtering;如果只是短期測試,也可以設定 TTL 到期日。請注意 TTL 日期以 UTC 計算,不是台灣時間。
步驟四:確認並複製 Token
點選 Continue to summary,確認權限與 Zone 後建立 Token。Token 密文只會完整顯示一次,請立即放進密碼管理器或正式的 Secret 管理服務。不要貼進 GitHub、WordPress 文章、聊天紀錄或公開截圖。
先驗證 API Token 是否有效
正式查 GraphQL 前,先用 Cloudflare 的 Verify Token API 確認 Token 本身是否有效。為了避免 Token 留在 Shell History,可以用隱藏輸入讀進環境變數:
read -s CLOUDFLARE_API_TOKEN
export CLOUDFLARE_API_TOKEN
echo
curl "https://api.cloudflare.com/client/v4/user/tokens/verify" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
成功時應該看到 success: true 與 status: active。這一步只證明 Token 沒有過期、撤銷或貼錯,並不代表它一定有權限讀取你接下來指定的帳號與網域。
取得 Cloudflare Zone ID
GraphQL 查詢通常不直接填網域名稱,而是使用 Zone ID,也就是查詢裡常看到的 zoneTag。
- 進入 Cloudflare 後台。
- 選擇要查詢的網站。
- 進入 Overview。
- 在右側 API 區塊找到 Zone ID。
- 複製後放進環境變數。
export CLOUDFLARE_ZONE_ID="你的_ZONE_ID"
Zone ID 不是 API Token,不需要當成密碼看待,但也不要把 Account ID、Zone ID 和 Token 混在一起。帳號層級資料使用 accountTag,網域層級資料使用 zoneTag。
用 curl 查詢 Cloudflare GraphQL Analytics
下面這個範例會查詢指定時段內,流量最高的 5 個 Cloudflare 機房,回傳請求數、造訪數與傳輸量。請先依自己的需求調整開始與結束時間。
curl --silent \
"https://api.cloudflare.com/client/v4/graphql" \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"query": "query TrafficByColo($zoneTag: string, $start: Time, $end: Time) { viewer { zones(filter: { zoneTag: $zoneTag }) { traffic: httpRequestsAdaptiveGroups(limit: 5, orderBy: [count_DESC], filter: { datetime_geq: $start, datetime_lt: $end, requestSource: \"eyeball\" }) { count sum { visits edgeResponseBytes } dimensions { coloCode } } } } }",
"variables": {
"zoneTag": "'"$CLOUDFLARE_ZONE_ID"'",
"start": "2026-08-10T00:00:00Z",
"end": "2026-08-11T00:00:00Z"
}
}' | jq .
這段查詢使用較新的 httpRequestsAdaptiveGroups。如果你在舊文章看到 httpRequests1mByColoGroups 或 httpRequests1dByColoGroups,Cloudflare 已提供遷移說明,新的節點以 count 表示請求數,並以 sum.edgeResponseBytes 表示資料傳輸量。
GraphQL 回傳 200,不一定代表成功
這是第一次串接最容易誤判的地方。一般 REST API 常用 HTTP 狀態碼判斷結果,但 GraphQL 即使回傳 HTTP 200,JSON 裡仍可能有 errors。
{
"data": null,
"errors": [
{
"message": "does not have access to the path..."
}
]
}
所以自動化程式不能只判斷 HTTP 200,還要檢查 errors 是否為 null。若你正在開發 WordPress 串接工具,也可以延伸閱讀我的 WordPress REST API 應用程式密碼教學,了解另一種 Token 型驗證方式。
常見錯誤與排除方式
| 錯誤 | 常見原因 | 排除方式 |
|---|---|---|
| 401 Unauthorized | Token 缺少、失效或 Header 格式錯誤 | 執行 verify,確認使用 Bearer Token |
| 403 not authorized | 帳號、Zone 或 Analytics 權限不足 | 檢查 Account Analytics Read 與 Zone Resources |
| zones are not authorized | 查詢的 Zone 不在 Token 範圍 | 確認 Zone ID 與 Token 指定網域 |
| unknown field | 節點或欄位已改名 | 查官方 Schema,改用目前支援的欄位 |
| query time range is too large | 查詢期間超過方案或節點限制 | 縮短時間範圍並分批查詢 |
| 429 rate limiter | 查詢頻率或複雜度過高 | 降低欄位、Zone 數量並稍後重試 |
Token 顯示 active,為什麼 GraphQL 還是 403?
因為 Verify Token 檢查的是「這把鑰匙還能不能使用」,GraphQL 檢查的是「這把鑰匙能不能進這個房間」。Token 有效和資源授權是兩件不同的事。請重新核對:
- Token 是否屬於正確的 Cloudflare 帳號。
- 權限是否包含 Account Analytics Read。
- Zone Resources 是否包含目標網域。
- 查詢中的 Zone ID 是否複製正確。
- 建立 Token 的使用者本身是否有該帳號權限。
這類「API 已開通,但權限還沒真正到位」的狀況,也常出現在 Google 服務。我整理過一篇 Google Business Profile API 權限排查流程,觀念可以交叉參考。
正式環境的安全做法
- 每一套服務建立獨立 Token,不要共用萬用 Token。
- 只給 Read,不需要修改就不要給 Edit。
- 只選需要的帳號與 Zone,不要習慣選 All resources。
- Token 放在環境變數、Secret Manager 或 CI/CD Secrets。
- 不要硬寫在 PHP、JavaScript、Git Repo 或 WordPress 前端。
- 正式伺服器有固定 IP 時,加入 Client IP 限制。
- 短期專案設定 TTL,用完立即撤銷。
- 懷疑外洩時直接 Rotate 或 Revoke,不要只修改程式。
如果你是用 Python 或 CLI 封裝自動化流程,可以再看我的 Python CLI 與 WordPress REST API 實作。核心觀念都是一樣的:權限要小、秘密不能進版本控制、錯誤回應要完整記錄。
Cloudflare GraphQL 查詢限制也要注意
Cloudflare GraphQL Analytics API 不是無限查詢。官方目前說明,Zone 查詢一次最多包含 10 個 Zone,Account 查詢一次只能包含 1 個 Account;預設使用者限制為 5 分鐘內 300 次 GraphQL 查詢。不同資料節點也會依方案限制可查詢的歷史時間、欄位數與回傳筆數。
另外,Adaptive 資料可能採用抽樣。同一段長時間範圍重複查詢,結果可能略有差異。要提高一致性,可以縮短查詢區間、使用帶有 Groups 的彙整節點,並明確加入排序條件。
結論:先把 Token 權限設對,再開始寫 GraphQL
Cloudflare GraphQL Analytics API 的查詢語法不算最難,真正容易卡住的是 Token 權限、Account、Zone 與資料節點之間的關係。我的建議是先完成三段式測試:第一步 Verify Token,第二步確認 Zone ID,第三步才執行最小 GraphQL 查詢。
當這三步都正常,再逐步加入國家、網址、狀態碼、防火牆事件或資料傳輸量等欄位。這樣遇到問題時,才能知道是憑證、權限、查詢語法,還是方案限制,而不是一次把所有東西混在一起猜。
參考資料
- Cloudflare:Configure an Analytics API token
- Cloudflare:GraphQL endpoint 與 HTTP Headers
- Cloudflare:使用 curl 執行 GraphQL 查詢
- Cloudflare:GraphQL API 錯誤回應
- Cloudflare:GraphQL API Limits
常見問題 FAQ
Cloudflare API Token 和 Global API Key 有什麼不同?
API Token 可以限制權限、帳號、Zone、來源 IP 與有效期限,適合正式串接;Global API Key 的權限範圍較大,外洩風險也更高。新系統應優先使用最小權限的 API Token。
GraphQL Analytics API Token 要設定什麼權限?
依 Cloudflare 官方教學,建立 Custom Token 後選擇 Account、Account Analytics、Read,並在 Zone Resources 限定可查詢的網域。正式環境不建議直接開放全部 Zone。
Token 驗證為 active,為什麼仍收到 403?
active 只代表 Token 本身有效。403 通常表示它沒有目標 Account、Zone 或 Analytics 資料的授權。請重新檢查權限範圍、Zone Resources、Zone ID,以及建立 Token 的使用者角色。
Cloudflare GraphQL API 回傳 HTTP 200 就代表成功嗎?
不一定。GraphQL 可能在 HTTP 200 的 JSON 回應中帶有 errors 陣列,因此程式除了檢查狀態碼,也必須確認 errors 是否為 null,並記錄錯誤訊息方便排查。
Cloudflare API Token 可以放在 WordPress JavaScript 裡嗎?
不可以。瀏覽器端 JavaScript 會把 Token 暴露給訪客。應由伺服器端 PHP、Worker 或後端 API 保存 Token,再由後端呼叫 Cloudflare,前端只取得必要的處理結果。



