본문으로 건너뛰기

사용자 마이그레이션

Logto는 기존 사용자들을 다른 아이덴티티 시스템에서 대량 또는 Just-in-Time 방식으로 마이그레이션하는 것을 지원합니다. 이 가이드에서는 Management API를 통해 사용자를 대량으로 가져오는 방법과 마이그레이션 전에 고려해야 할 사항을 설명합니다.

마이그레이션 전략 선택하기​

전략선택 시기작동 방식
대량 마이그레이션사용자 레코드와 비밀번호 해시를 Logto가 지원하는 형식으로 내보낼 수 있을 때.이 가이드의 나머지 부분을 따라 Management API를 통해 전환 전에 사용자를 가져옵니다.
Just-in-Time 마이그레이션기존 시스템에서 비밀번호를 검증해야 하거나, 호환되는 비밀번호 해시를 내보낼 수 없거나, 활성 사용자를 점진적으로 마이그레이션하고 싶을 때.Post first-factor verification Action을 구성하세요. 사용자가 처음으로 비밀번호로 로그인할 때, Logto는 Action을 통해 자격 증명을 검증하고, 사용자를 생성 또는 업데이트하며, 새로운 로컬 비밀번호 해시를 저장합니다.

Just-in-Time 마이그레이션은 사용자가 마이그레이션될 때까지 기존 인증 (Authentication) 서비스를 로그인 요청 경로에 유지합니다. 빠르고 신뢰할 수 있는 HTTPS 엔드포인트를 사용하고, 마이그레이션 기간 동안 이를 사용할 수 있도록 하세요.

사용자 스키마​

시작하기 전에, Logto의 사용자 스키마를 살펴보겠습니다. 사용자 스키마에는 알아야 할 3가지 부분이 있습니다:

  1. 기본 데이터: 사용자 프로필의 기본 정보로, 기존 사용자 프로필의 데이터를 매칭할 수 있습니다.
  2. 커스텀 데이터: 추가 사용자 정보를 저장하며, 기본 데이터와 매칭할 수 없는 파일을 저장하는 데 사용할 수 있습니다.
  3. 소셜 아이덴티티: 소셜 로그인에서 가져온 사용자 정보를 저장합니다.

기존 사용자 프로필의 정보를 기본 데이터와 커스텀 데이터에 매핑하는 맵을 만들 수 있습니다. 소셜 로그인의 경우, 소셜 아이덴티티를 가져오기 위한 추가 단계가 필요합니다. 자세한 내용은 사용자에 소셜 아이덴티티 연결 API를 참조하세요.

기존 사용자 ID 유지하기​

기본적으로, Logto는 Management API를 통해 생성된 모든 사용자에게 무작위 ID를 생성합니다. 애플리케이션이 이미 이전 아이덴티티 제공자의 사용자 ID를 저장하고 있다면, create user 요청 본문에 선택적으로 id를 전달하여 이를 유지할 수 있습니다. 이렇게 하면 이전 ID와 새 ID 간의 매핑 테이블을 유지할 필요가 없습니다.

ID는 1~128자 사이여야 하며, 영문자, 숫자, _ - . @ : + = |를 포함할 수 있습니다. 이는 auth0|5f7c8ec7c33c6c004bbafe82, google-oauth2|103547991597142817347, UUID, user_01H8MZ2QK3V4X5Y6Z7, 이메일 주소 등 일반적인 형식을 모두 포함합니다. URL 경로에 유효하지 않은 문자(공백, /, ?, #, %, \)는 /api/users/{userId}에서 사용되므로 400 오류로 거부됩니다. 이미 사용 중인 ID라면, 요청은 422 user.id_already_in_use로 실패합니다.

{
"id": "auth0|5f7c8ec7c33c6c004bbafe82",
"primaryEmail": "john.doe@example.com",
"passwordAlgorithm": "Bcrypt",
"passwordDigest": "$2b$10$..."
}
노트:

커스텀 사용자 ID는 셀프 호스팅 Logto에서만 지원됩니다. Logto Cloud는 id가 포함된 요청을 501 request.feature_not_supported로 거부합니다. 이는 사용자 ID가 테넌트 간에 공유되기 때문입니다.

비밀번호 해싱​

Logto는 사용자의 비밀번호를 해싱하기 위해 Argon2를 사용하며, 마이그레이션의 편의를 위해 MD5, SHA1, SHA256, Bcrypt와 같은 다른 알고리즘도 지원합니다. 이러한 알고리즘은 안전하지 않으므로, 해당 비밀번호 해시는 사용자가 처음 성공적으로 로그인할 때 Argon2로 마이그레이션됩니다.

다른 해싱 알고리즘이나 솔트를 사용하는 경우, passwordAlgorithm을 Legacy로 설정할 수 있습니다. 이를 통해 Node.js에서 지원하는 모든 해시 알고리즘을 사용할 수 있습니다. 지원되는 알고리즘 목록은 Node.js crypto 문서에서 확인할 수 있습니다. 이 경우, passwordDigest는 해시 알고리즘 및 기타 알고리즘별 매개변수를 포함하는 JSON 문자열이 됩니다.

일반 Legacy 포맷​

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');

PBKDF2 지원​

Logto는 PBKDF2를 특별히 지원합니다.

PBKDF2로 해싱된 비밀번호를 마이그레이션하려면, passwordAlgorithm을 Legacy로 설정하고 passwordDigest를 다음과 같이 포맷하세요:

["pbkdf2", ["salt", "1000", "20", "sha512", "@"], "expected_hashed_value"]

각 매개변수는 다음과 같습니다:

  • salt: 원래 해싱에 사용된 솔트 값
  • iterations: 반복 횟수 (예: "1000")
  • keylen: 파생 키의 바이트 길이 (예: "20")
  • digest: 사용된 해시 함수 (예: "sha512", "sha256", "sha1")
  • @: 실제 비밀번호 값을 위한 플레이스홀더
  • expected_hashed_value: 16진수 문자열로 된 예상 해시 결과

마이그레이션 예시 페이로드:

{
"username": "john_doe",
"primaryEmail": "john.doe@example.com",
"passwordAlgorithm": "Legacy",
"passwordDigest": "[\"pbkdf2\", [\"mySalt123\", \"1000\", \"20\", \"sha512\", \"@\"], \"c465f66c6ac481a7a17e9ed5b4e2e7e7288d892f12bf1c95c140901e9a70436e\"]"
}

마이그레이션 단계​

  1. 사용자 데이터 준비 먼저 기존 플랫폼에서 사용자 데이터를 내보내고, 사용자 정보를 Logto 사용자 스키마에 매핑해야 합니다. 매핑된 데이터를 JSON 형식으로 준비하는 것을 권장합니다. 사용자 데이터 예시는 다음과 같습니다:

    [
    {
    "username": "user1",
    "passwordDigest": "password-encrypted",
    "passwordAlgorithm": "SHA256"
    },
    {
    "username": "user2",
    "passwordDigest": "password-encrypted",
    "passwordAlgorithm": "SHA256"
    }
    ]
  2. Logto 테넌트 생성 Logto에서 테넌트를 설정해야 합니다. Logto Cloud 또는 Logto OSS를 사용할 수 있습니다. 아직 설정하지 않았다면, Logto Cloud 설정 가이드를 참고하세요.

  3. Management API 연결 설정 Management API를 사용하여 사용자 데이터를 가져올 예정입니다. 개발 환경에서 연결을 설정하는 방법은 Management API를 참고하세요.

  4. 사용자 데이터 가져오기 사용자 데이터를 하나씩 가져오는 스크립트를 준비하는 것이 좋습니다. 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),
    });
    // 속도 제한을 피하기 위해 잠시 대기
    await new Promise((resolve) => setTimeout(resolve, 200));
    } catch (error) {
    console.error(`사용자 ${user.username} 가져오기 실패: ${error.message}`);
    }
    }
    };

    importUsers();

API 엔드포인트는 속도 제한이 있으므로, 각 요청 사이에 대기 시간을 추가하여 속도 제한을 피해야 합니다. 자세한 내용은 속도 제한 페이지를 참고하세요.

사용자 데이터가 대량(10만 명 이상)인 경우, 문의해 주세요 속도 제한 상향을 요청할 수 있습니다.

기존 사용자 데이터베이스를 Logto로 마이그레이션하는 일반 가이드