為什麼 refreshToken 錯誤會在 n8n 環境中出現?

我正在執行多個 n8n 實例(開發/測試/生產),並使用 Microsoft Entra ID 認證來查詢 Microsoft Graph(依 userId 列出聊天、聊天成員等)。

當我將工作流程從 n8n-dev 部署到 n8n-rec 時,工作流程在第一次排定執行時系統性地失敗,顯示:「refreshToken is required」/ ERR_ASSERTION。

唯一的恢復方式是手動開啟認證並在目標實例上點擊「重新連接」。幾小時後或下次部署時,問題會再次出現。

我懷疑這是三種已知行為的組合,但我想得到 n8n 團隊的確認以及多環境設置的最佳實踐指導。

我認為發生的情況

  1. 認證不會隨工作流程匯出傳輸。工作流程 JSON 只包含認證參考(id + name),不包含加密的令牌 blob。這是預期的行為。

  2. 原始碼控制與環境明確排除認證。根據官方文件(https://docs.n8n.io/external-secrets/):「此功能不支援在不同實例中使用不同認證。」

  3. Microsoft Entra 使用刷新令牌輪換。每次刷新呼叫都會使舊的 refresh_token 失效並發行新的。因此,如果同一認證記錄存在於兩個實例(開發 + 測試),無論哪個實例先刷新都會燒毀另一個的令牌,導致第二個實例出現「refreshToken is required」。這在問題 #26453https://github.com/n8n-io/n8n/issues/26453)中有記載:「Microsoft Entra ID 在每次使用時都會用新令牌替換刷新令牌。如果 n8n 未保存新的刷新令牌,後續刷新嘗試可能會失敗。」這也在 Entra ID 節點上的社群討論串 #193787https://community.n8n.io/t/entra-id-node-reconnection-issues/193787)和問題 #14426https://github.com/n8n-io/n8n/issues/14426)中有重現。

此節點是指向 https://graph.microsoft.com/v1.0/users/{id}/chats 的 HTTP Request 節點,使用 Microsoft Entra ID(Azure Active Directory)API 預定義認證類型。

工作流程

工作流程輸入 → 依 USERID 列出聊天(HTTP Request、Graph API、在此失敗)-> 分割出列表值 → 迴圈遍歷聊天 → 按主題篩選聊天 → 如果為真:取得聊天成員 → 使用者資訊 / 如果為假:非主題聊天名稱 → 迴圈結束。

歡迎 @Rodolphe24 加入我們的社群!我是 Jay,我是 n8n 認證創作者。

您的根本原因分析完全正確。Microsoft Entra ID 使用重新整理令牌輪換,所以無論哪個環境先呼叫令牌端點,都會使另一個環境上的令牌失效。解決方案是將每個環境視為完全獨立的 OAuth 應用程式 - 在 Azure 中為開發環境和測試環境各建立一個不同的應用程式註冊,每個都有自己的用戶端 ID/祕密和指向該環境 n8n 實例的專屬重新導向 URI。永遠不要在多個實例中共用相同的憑證記錄。設定完成後,每個環境會獨立管理自己的重新整理週期,令牌失效問題就會停止。

早上好 @Rodolphe24

我也會避免在期望認證資料一起的情況下推廣工作流程。我在這類情況下通常做的是在 dev/rec/prod 中保持相同的邏輯認證資料名稱,但在每個實例中使用該環境的應用程式註冊來本地重新連接/建立認證資料。這樣工作流程仍然可以很容易地通過原始碼管制進行推廣,但每個環境都保持自己的 OAuth 狀態和自己的重新整理令牌週期。在 pull/deploy 之後,也值得檢查已匯入的工作流程是否指向目標環境中的正確認證資料。

感謝您的輸入 — 這其實就是我已經在執行的模式:

  • 在開發/預備/生產環境中使用相同的邏輯認證名稱

  • 每個環境分別建立 Azure 應用程式註冊

  • 每個認證在其各自的執行個體上本地重新連接

部署後,工作流程確實指向目標上的正確認證。在發佈工作流程之前,我已經成功啟動過它。所以我不明白…

@Rodolphe24
我會調查兩件事:認證在重新連線時是否真的收到了刷新令牌,特別是在使用了正確的 offline_access/admin consent 的情況下,以及同一實例的所有容器/工作者是否都使用相同的 N8N_ENCRYPTION_KEY。

嗨,感謝你的反饋。這是否可能與 n8n worker 的問題有關?當我手動運行工作流時,它能正常運作。但是,當我發佈後使用排程器節點觸發主工作流時,我遇到了重新整理令牌的錯誤。

是的,這幾乎肯定是一個 worker 問題。當排程工作流通過 worker 運行時,worker 需要與主實例相同的 N8N_ENCRYPTION_KEY 來解密儲存的認證資訊。如果它們不同,令牌解密會失敗,你會收到刷新令牌錯誤。檢查你的 worker 環境變數,並確認 N8N_ENCRYPTION_KEY 與主實例相匹配。還要確保 worker 能夠訪問儲存認證資訊的相同資料庫 - 連接到不同資料庫的 worker 根本看不到該令牌。

關於 refreshToken 錯誤的觀察

我針對 refreshToken is required 錯誤進行了多項測試:

  • 測試 1:
    在具有唯讀權限的 n8n-rec 執行個體上,啟動工作流程失敗,出現以下錯誤:
    refreshToken is required

  • 測試 2:
    在具有讀寫權限的 n8n-rec 執行個體上,啟動工作流程出現相同的錯誤:
    refreshToken is required

  • 測試 3:
    在具有讀寫權限的 n8n-rec 執行個體上手動重新連接 Microsoft Entra ID 後,工作流程成功啟動,沒有任何錯誤。

在具有讀寫權限的 n8n-dev 執行個體上,已發佈的工作流程不會出現此錯誤。

@Rodolphe24 很棒的測試分解。你的測試 3 結果是合理的 — 當你在 n8n-rec 上手動重新連接認證時,Microsoft 會發出一個包含 offline_access 作用域的新 OAuth 令牌(刷新令牌所需)。儲存在 n8n-rec 中的舊認證可能有一個過期的或作用域受限的令牌,來自於它最初設置時的狀態。

關鍵要點:如果在 n8n-rec 上使用讀/寫重新連接有效,那麼原始認證缺少 offline_access 作用域。為了避免這個問題重複發生,請確保你的 Azure 應用程式註冊已啟用該作用域,並在每個實例上分別重新授權。

  1. 在 Azure 中建立個別的應用程式註冊:Dev、Rec 和 Prod 各一個。
  2. 使用標準環境變數將用戶端設定注入到不同的 n8n 伺服器執行個體:
  • MICROSOFT_CLIENT_ID
  • MICROSOFT_CLIENT_SECRET
  • MICROSOFT_TENANT_ID
  1. 在 HTTP 要求節點中,將驗證類型切換為通用認證類型 → OAuth2。
  2. 在認證設定欄位中,使用 n8n 運算式來參考環境變數:
  • 用戶端識別碼:{{$env.MICROSOFT_CLIENT_ID}}
  • 用戶端密碼:{{$env.MICROSOFT_CLIENT_SECRET}}

由於 n8n 會針對每個執行個體原生評估環境變數,所以工作流程 JSON 在 Dev、Rec 和 Prod 之間保持相同,但每個執行個體都會連接到自己隔離的 Azure 容器。

請告訴我這是否可行,如果不行,我有另一個解決方案。

好的,感謝你的回饋,我來試試看。

您好,感謝您的反饋,這不太可能,因為我必須使用基於 Microsoft Graph 的特定驗證:Microsoft Entra ID(Azure Active Directory)API,它也是基於 oauth2

很高興聽到我的回覆很有幫助,並被選為解決方案——真的讓我很開心!

如果你在這個主題或其他 n8n 設定上有任何進一步的問題,歡迎隨時告訴我,我很樂意深入探討。

@Rodolphe24
在部署之後,在點擊「重新連接」之前,REC 認證仍然包含有效的 OAuth 狀態,這是排程執行使用的相同認證嗎?

如果可能的話,請分享部署方法、REC 的架構(單一實例或佇列模式/工作程式/多個容器)、重新連接之前的證據、部署後首次排程執行的完整日誌。