嘿!
我在 GCP CloudRun 上運行 n8n,搭配 PostgreSQL。我們有幾個為不同需求服務的實例。
在其中一個實例上,第一位用戶註冊後成為了擁有者。他是這個實例上唯一的擁有者/管理員。他忘記了密碼,無法恢復,因為我們沒有配置 SMTP。
重設密碼最簡單的方法是什麼?
直接在資料庫中將角色變更為 global:admin 是否安全,然後註冊一個新的擁有者來生成重設密碼連結?
嘿!
我在 GCP CloudRun 上運行 n8n,搭配 PostgreSQL。我們有幾個為不同需求服務的實例。
在其中一個實例上,第一位用戶註冊後成為了擁有者。他是這個實例上唯一的擁有者/管理員。他忘記了密碼,無法恢復,因為我們沒有配置 SMTP。
重設密碼最簡單的方法是什麼?
直接在資料庫中將角色變更為 global:admin 是否安全,然後註冊一個新的擁有者來生成重設密碼連結?
嘿 @rgrzesk,在等待回應期間,以下是一些可能對你有幫助的資源:
@moosa、@gusgvd、@mechanizedgrowth — 你們之前幫助解決過類似的問題,能看一下嗎?
由 n8n 社區機器人自動建議。這是一個試點 — 請在此分享反饋。
嗨 @rgrzesk
這是重設使用者的一種方式。
這不會刪除任何其他資料,例如工作流程或認證資訊。只會刪除使用者。
Hi @rgrzesk
既然你已經在 GCP 生態系中,你可以使用 Cloud Shell 直接連接到你的 Cloud SQL 實例,並手動更新密碼雜湊。這樣就不需要在本地執行 n8n 或管理加密密鑰。
gcloud sql connect [YOUR_INSTANCE_NAME] --user=postgres
bcrypt,你不能只輸入純文字密碼。你可以在 Cloud Shell 中使用這個 Python 單行指令來為你所需的密碼(例如 NewPassword123!)產生雜湊:python3 -c 'import bcrypt; print(bcrypt.hashpw(b"NewPassword123!", bcrypt.gensalt()).decode())'
複製產生的字串(它以 $2b$... 開頭)。
user 是 PostgreSQL 中的保留關鍵字,所以它必須用雙引號包裹。UPDATE "user"
SET "password" = '[PASTE_YOUR_HASH_HERE]'
WHERE "email" = '[OWNER_EMAIL_ADDRESS]';
SELECT email FROM "user" WHERE email = '[OWNER_EMAIL_ADDRESS]';
\q
嗨 @rgrzesk 歡迎!
你的 global:admin 方案行不通——設置精靈受限於 settings 鍵 userManagement.isInstanceOwnerSetUp = true,而不是 global:owner 列是否存在,所以降級所有者會導致你沒有所有者,仍然無法訪問 /setup。(global:admin 也是企業版許可的角色。)
既然你使用 Postgres,只需覆蓋該用戶的 bcrypt 哈希值。一列,不涉及其他內容,無需重新部署:
1. 生成哈希值(n8n 使用 bcryptjs,成本係數 10):
docker run --rm node:20-alpine sh -c \
"npm i bcryptjs --silent --prefix /tmp >/dev/null 2>&1 && \
node -e \"console.log(require('/tmp/node_modules/bcryptjs').hashSync('YourNewPass1',10))\""
使用符合 n8n 規則的密碼(8–64 個字符,1 個數字,1 個大寫字母),否則你稍後無法在 UI 中更改它。
2. 連接並更新:
UPDATE "user"
SET password = '$2b$10$...your hash...'
WHERE email = 'owner@yourdomain.com';
容易出錯的兩點:user 是 Postgres 中的保留字,必須用雙引號包圍,哈希值必須用單引號包圍,否則 bash 會展開 $2b/$10 並寫入垃圾數據。
如果該帳戶啟用了多因素認證,還要執行 SET "mfaEnabled" = false, "mfaSecret" = NULL, "mfaRecoveryCodes" = NULL。
3. 從無痕窗口登錄——n8n 從密碼哈希值衍生出部分驗證 JWT,所以舊會話失效,過期的 cookie 會被拒絕。無需重啟容器。
在此情況下避免使用 n8n user-management:reset:你無法 docker exec 進入 Cloud Run,它會清除所有用戶帳戶並將實例返回到設置精靈。之後值得在 Cloud Run 服務上添加 SMTP 環境變數,以防止整個隊伍再次發生此情況。
我曾試過(在我的測試實例上)將其他用戶從 global:owner 改為 global:admin,結果成功了。進入實例後,我又看到了 /setup 畫面。所以這個技巧效果不錯。
問題是 - 這樣安全嗎?這些角色是否也被保存/使用在其他地方?
那就是我計劃要做的一個穩固且長期的解決方案
目前我只是試著快速恢復實例,而不需要額外的部署。
你說得對,我的錯 — 較新版本的 n8n 是根據是否存在 global:owner 列來決定是否顯示 /setup,而不是我引用的設定金鑰。感謝你測試。
關於安全性:有三個不同的 role 欄位,它們是分開的東西。user.role 是實例角色(你修改的那個)。project_relation.role 和 shared_workflow/shared_credentials.role 處理專案成員資格和資源所有權 — 而且這些是以 projectId 而非 userId 作為金鑰。所以你做的任何事都不會改變誰擁有哪個工作流程或認證。那部分沒問題。
我會改變的一件事:使用 global:member 而不是 global:admin。Admin 是 Pro/Enterprise 帳戶類型,所以在 Community 上你把使用者放在實例無法授權的角色中 — UI 往往會將未授權的角色灰顯,所以你可能無法在沒有另一個資料庫寫入的情況下改回。Member 可以讓你看到同樣的設定畫面,而不會有任何問題。
所以:快照資料庫 → 將舊擁有者設定為 global:member → 註冊一個臨時擁有者 → 設定 → 使用者 → 複製舊帳戶的密碼重設連結(不需要 SMTP 也能運作)→ 重設 → 將角色改回 → 刪除臨時使用者。不要同時保留兩個 global:owner 列。
無論如何,值得在所有 Cloud Run 服務上設定 N8N_EMAIL_MODE=smtp — 由於每個實例只有一個擁有者,這個問題遲早會出現。
嗨 @rgrzesk
從 n8n 2.17.0 開始,實例擁有者可以從環境變數佈建,這樣可以重設密碼而完全不需要觸碰資料庫。在 Cloud Run 服務上設定這些變數,使用現有擁有者的電子郵件:
N8N_INSTANCE_OWNER_MANAGED_BY_ENV=true
N8N_INSTANCE_OWNER_EMAIL=owner@yourdomain.com
N8N_INSTANCE_OWNER_FIRST_NAME=Firstname
N8N_INSTANCE_OWNER_LAST_NAME=Lastname
N8N_INSTANCE_OWNER_PASSWORD_HASH=<bcrypt hash>
n8n 會在每次啟動時重新應用這些設定到現有的擁有者帳戶,所以修訂版本會在密碼已更改的狀態下啟動。當啟用這個標誌時,該使用者在 UI 中是唯讀的,他們的 API 寫入會被拒絕,所以一旦你進入系統,設定 N8N_INSTANCE_OWNER_MANAGED_BY_ENV=false,它套用的值會保留在原位,UI 就會再次解鎖。
它只需要一個修訂版本,但無需編輯角色,資料庫中也沒有任何東西需要復原,這就是可以跨其他實例擴展的地方。