Google Ads API via HTTP Request node:如何在不硬編碼的情況下注入 developer-token 標頭?

大家好,

我從 HTTP Request 節點呼叫 Google Ads API,因為原生的 Google Ads 節點只支援「取得行銷活動」,而我需要其他端點。

我的設定:

  • HTTP Request 節點
  • Authentication → Predefined Credential Type → Google Ads OAuth2 API(這個正確處理 OAuth Bearer token)

問題:呼叫失敗,出現 DEVELOPER_TOKEN_PARAMETER_MISSING 錯誤。HTTP Request 節點不會自動從 Google Ads OAuth2 憑證注入 developer-token 標頭,所以我必須手動新增。

我的嘗試:我新增了手動標頭 developer-token,並用表達式設定值,讓 token 留在工作流程 JSON 之外:

={{ $credentials.developerToken }}

這對我來說沒有效果。表達式似乎解析為空,所以 token 仍然遺失,我得到相同的錯誤。我猜測 $credentials 出於安全原因在 HTTP Request 節點表達式內沒有公開,但我不確定。

我的問題:

  1. 有沒有支援的方式在 HTTP Request 節點內參考現有 Google Ads OAuth2 憑證中的 developer-token,而不需要內嵌輸入 token?現在我把它存放在 $env 中,但我想改變這個做法。
  2. 如果 $credentials 在那裡不可用,保持 token 不在工作流程匯出中的推薦方法是什麼?

我使用自託管實例(Elestio)。提前感謝任何指引。

@jochem 你說得沒錯,$credentials 在節點表達式中並未暴露(僅在憑證欄位內部),所以該標題會解析為空,目前沒有支援的方式可以將 OAuth2 憑證中的開發人員令牌提取到 HTTP 節點。保持使用 OAuth2 進行驗證,並將開發人員令牌標題值設定為變數,在雲端/企業版本上使用 {{ $vars.googleAdsDevToken }}(變數功能),或在自託管版本上使用 {{ $env.GOOGLE_ADS_DEV_TOKEN }},如此令牌就不會出現在工作流程 JSON 中。

在 HTTP 要求標頭值運算式中,$credentials 速記無法存取。該物件僅在自訂憑證類型定義內公開,不在節點欄位中。

對於 n8n Cloud,最簡潔的做法是使用 n8n 變數(設定 > 變數)。建立一個變數(例如 GOOGLE_ADS_DEV_TOKEN)並將開發者權杖存放在該處。然後在 HTTP 要求標頭值欄位中使用:

{{ $vars.GOOGLE_ADS_DEV_TOKEN }}

變數的範圍限於工作區,永遠不會出現在已匯出的工作流程 JSON 中,且在 Cloud 的 Starter 方案及以上版本中可用。

如果是自我託管,替代方案是環境變數。在 Docker 環境中設定 GOOGLE_ADS_DEV_TOKEN=xyz,然後在標頭中參考它:

{{ $env.GOOGLE_ADS_DEV_TOKEN }}

$env 存取需要 N8N_BLOCK_ENV_ACCESS_IN_NODE=false(預設值)為使用中。在 Cloud 上,你無法設定環境變數,所以變數是正確的做法。

還值得檢查的是:Google Ads API 通常在子帳號範圍的端點上需要 login-customer-id 標頭(你的 MCC 客戶 ID,不含連字號)。缺少該標頭是常見的第二個錯誤原因,與開發者權杖並列。

嗨各位,感謝各位快速回應。確實在自託管環境中使用 $env 變數是可行的。到目前為止,我一直都採用這種方法。

我最近升級到 n8n v2,我發現出於安全考慮,使用 $env 變數似乎不再被鼓勵。這就是為什麼我很好奇是否有人知道自託管環境中的更好替代方案。

目前,我會繼續使用 N8N_BLOCK_ENV_ACCESS_IN_NODE=false。

我很樂意聽聽是否有其他更好的替代方案 :slight_smile:

@jochem 在社群自託管版本上,使用 N8N_BLOCK_ENV_ACCESS_IN_NODE=false 搭配 $env 確實是預期的做法,預設的封鎖只是一種防護機制,以防工作流程意外讀取主機環境變數。刻意允許讀取一個已知的秘密並不是錯誤的做法。唯一更安全的內建選項是外部秘密管理 ($secrets,與 Vault / AWS / Azure / GCP 秘密管理器整合),但那只有企業自託管版本才支援。所以在社群版本上沒有更好的替代方案,你繼續使用 $env 方法是沒問題的。

你診斷得沒錯 — $credentials 在節點表達式中刻意不被暴露,所以 {{ $credentials.developerToken }} 會解析為空。HTTP Request 節點只會從 Google Ads 認證中注入 OAuth2 Bearer,不會注入 developer-token 欄位 — 沒有切換開關可以傳遞它,而且你也無法附加第二個預定義認證。所以 token 必須來自某個可引用的地方。

保持它不在工作流匯出中的選項:

  • $env 實際上是一種受支援的方法 — 它確實能讓 token 不進入工作流 JSON,所以保留在那裡沒問題,只是不太方便。
  • n8n 變數({{ $vars.googleAdsDeveloperToken }})— 效果相同,但在 UI 中管理,如果你的方案包含變數功能。
  • 適當的單一認證修正:建立一個小型自訂認證類型,擴展 Google Ads OAuth2 認證,使其在 authenticate 區塊中也將 developer-token(和 login-customer-id)注入為標頭。這樣單一預定義認證就能處理 Bearer 和 dev-token,HTTP Request 節點不需要手動標頭,沒有任何東西進入匯出。你在 Elestio 上自架,所以可以放入自訂認證 — 這是長期最簡潔的答案,給你正好是你想要的「從認證中引用它,無內聯」行為。

答案:否,不支援從 HTTP Request 節點表達式內存取憑證 (credentials) 欄位。憑證僅用於驗證 (OAuth2),並不會暴露給表達式,因此您無法編寫:答案:否,不支援從 HTTP Request 節點表達式內存取憑證 (credentials) 欄位。憑證僅用於驗證 (OAuth2),並不會暴露給表達式,因此您無法編寫: