使用者遷移 (User migration)
Logto 支援手動將現有使用者從其他平台遷移,本指南將說明如何透過 Management API 匯入現有使用者,並介紹遷移前你應考慮的事項。
使用者結構 (User schema)
在開始之前,讓我們先看看 Logto 的 使用者結構。你需要注意使用者結構的三個部分:
- 基本資料 (Basic data):來自使用者檔案的基本資訊,你可以將現有使用者檔案的資料對應到這裡。
- 自訂資料 (Custom data):儲存額外的使用者資訊,適合存放無法對應到基本資料的欄位。
- 社交身分 (Social identities):儲存從社交登入取得的使用者資訊。
你可以建立一個對應表,將現有使用者檔案的資訊對應到 基本資料 (basic data) 與 自訂資料 (custom data)。若有社交登入,需額外步驟匯入社交身分,請參考 連結社交身分至使用者 (Link social identity to user) 的 API。
密碼雜湊 (Password hashing)
Logto 使用 Argon2 進行使用者密碼雜湊,並為遷移方便,也支援 MD5
、SHA1
、SHA256
和 Bcrypt
等其他演算法。這些演算法被認為不安全,對應的密碼雜湊值會在使用者首次成功登入時自動遷移為 Argon2。
如果你使用其他雜湊演算法或加鹽,可以將 passwordAlgorithm
設為 Legacy
,這樣可使用 Node.js 支援的任何雜湊演算法。支援的演算法列表可參考 Node.js crypto 文件。此情況下,passwordDigest
需為包含雜湊演算法及其他參數的 JSON 字串。
JSON 字串格式如下:
["hash_algorithm", ["argument1", "argument2", ...], "expected_hashed_value"]
你可以用 @
作為參數中的實際密碼值佔位符。
例如,若你使用 SHA256 並加鹽,可將密碼儲存為下列格式:
["sha256", ["salt123", "@"], "c465f66c6ac481a7a17e9ed5b4e2e7e7288d892f12bf1c95c140901e9a70436e"]
這等同於以下程式碼:
const hash = crypto.createHash('sha256');
hash.update('salt123' + 'password123');
const expectedHashedValue = hash.digest('hex');
遷移步驟 (Steps to migrate)
-
準備使用者資料 (Prepare the user data) 你應先從現有平台匯出使用者資料,並將使用者資訊對應到 Logto 的使用者結構。我們建議你將對應後的資料整理為 JSON 格式。以下為使用者資料範例:
[
{
"username": "user1",
"passwordDigest": "password-encrypted",
"passwordAlgorithm": "SHA256"
},
{
"username": "user2",
"passwordDigest": "password-encrypted",
"passwordAlgorithm": "SHA256"
}
] -
建立 Logto 租戶 (Create a Logto tenant) 你需要在 Logto 建立一個租戶。可選擇 Logto Cloud 或 Logto OSS。若尚未建立,請參考 設定 Logto Cloud 指南。
-
設定 Management API 連線 (Setup the connection of Management API) 我們將使用 Management API 匯入使用者資料,請參考 Management API 了解如何在開發環境中設定連線。
-
匯入使用者資料 (Import the user data) 建議你撰寫腳本逐一匯入使用者資料,將呼叫 建立使用者 (create user) API 來匯入。以下為腳本範例:
const users = require('./users.json');
const importUsers = async () => {
for (const user of users) {
try {
await fetch('https://[tenant_id].logto.app/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer [your-access-token]',
},
body: JSON.stringify(user),
});
// Sleep for a while to avoid rate limit
await new Promise((resolve) => setTimeout(resolve, 200));
} catch (error) {
console.error(`Failed to import user ${user.username}: ${error.message}`);
}
}
};
importUsers();
請注意 API 端點有速率限制,你應在每次請求間加入延遲以避免觸發限制。詳情請參閱 速率限制 (rate limits) 頁面。
若你有大量使用者資料(10 萬以上),可聯絡我們以提升速率限制。
相關資源 (Related resources)
將現有使用者資料庫遷移至 Logto 的一般指引