> ## Documentation Index
> Fetch the complete documentation index at: https://docs.replit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 기존 앱을 Clerk Auth로 마이그레이션하기

> 사용자 계정이나 과거 데이터를 잃지 않고 기존 앱을 Clerk Auth로 마이그레이션하기 위한 모범 사례입니다.

앱에 이미 작동하는 인증 시스템과 실제 사용자 데이터베이스가 있다면, [Clerk Auth](/ko/features/auth-and-identity/clerk-auth)로 전환하는 것은 **단순한 코드 변경이 아니라** 데이터 마이그레이션입니다. 신중한 계획이 없다면, `users` 테이블에 있는 기존 행 하나하나가 Clerk에게는 낯선 존재가 됩니다. 새 계정은 첫 로그인 시 생성되고, 그 계정들은 과거 데이터와 전혀 일치하지 않으며, 기존 고객들은 마치 계정을 "잃어버린" 것처럼 보이게 됩니다.

실제로 제대로 처리해야 할 것은 딱 두 가지뿐입니다.

<Note>
  이 페이지는 **커스텀 인증 솔루션**(자체 사용자 테이블, 비밀번호 해싱, 세션 등)에서 Clerk Auth로 마이그레이션하는 경우만 다룹니다. [Replit Auth](/ko/features/auth-and-identity/authentication)에서 Clerk Auth로 앱을 이전하는 가이드는 **아닙니다** — 해당 마이그레이션 경로에 대한 공식 가이드는 곧 제공될 예정입니다.

  새 앱을 시작하는 경우라면 [Clerk Auth 개요](/ko/features/auth-and-identity/clerk-auth)를 참고하세요 — 마이그레이션이 필요하지 않습니다.
</Note>

## 1. 기존 사용자를 Clerk로 가져오기

앱의 모든 활성 사용자는 Clerk Auth가 라이브로 전환되기 *전에* Clerk 사용자로 존재해야 합니다. 각 가져오기에는 최소한 다음이 포함되어야 합니다.

* **이메일**(필수)
* **사용 가능한 프로필 메타데이터**: 이름, 인증 상태, Auth 패널에 표시하고 싶은 그 외의 정보
* **비밀번호 다이제스트**: 사용자의 기존 비밀번호 해시
* **비밀번호 해셔**: 해당 해시의 알고리즘/형식, Clerk가 요구하는 정확한 형태

해셔는 실수하기 쉬운 부분입니다. Clerk는 정해진 비밀번호 해시 형식만 허용하며, 각각 특정 문자열 식별자(`bcrypt`, `scrypt_firebase`, `argon2i`, `pbkdf2_sha256` 등)를 가지고 있습니다. 전체 목록과 각각에 필요한 정확한 다이제스트 형식은 [Clerk Create User API 레퍼런스](https://clerk.com/docs/reference/backend/user/create-user)에서 확인하세요.

이 단계는 한 줄짜리 프롬프트로는 부족합니다. 마이그레이션을 담당하는 Agent는 **현재 코드베이스에서 비밀번호가 어떻게 해싱되는지에 대한 철저한 이해**가 필요합니다 — 어떤 라이브러리를 사용하는지, 어떤 매개변수(cost factor, salt 구조, pepper 등)를 사용하는지, 그리고 그것이 Clerk가 지원하는 해셔 중 어느 것에 매핑되는지 알아야 합니다. 잘 작성된 프롬프트는 다음과 비슷한 형태입니다.

```
내 기존 인증 코드를 읽고 비밀번호가 정확히 어떻게 해싱되는지 파악해줘
(라이브러리, 알고리즘, 매개변수, 저장된 값의 형식).
그런 다음 users 테이블의 모든 사용자에 대해, 이메일, 프로필 메타데이터,
일치하는 Clerk 해셔가 요구하는 정확한 형식의 비밀번호 다이제스트,
올바른 passwordHasher 값을 사용해 Clerk Backend API를 호출하는
일회성 가져오기 스크립트를 작성해줘. 실행하기 전에 어떤 Clerk 해셔를
선택했는지, 그리고 그 이유를 알려줘.
```

해싱 방식이 Clerk가 지원하는 해셔 중 어느 것에도 깔끔하게 매핑되지 않는다면, 가져온 사용자는 기존 비밀번호로 로그인할 수 없게 됩니다. 이런 경우에는 다이제스트 없이 가져온 다음, 전환 시점에 비밀번호 재설정 이메일을 보내세요.

## 2. Clerk 사용자를 기존 사용자 ID로 다시 연결하기

가져온 사용자가 로그인하면, 인증된 모든 요청에는 Clerk ID가 포함됩니다. 서버는 그 ID를 `users` 테이블의 행으로 다시 매핑해야 합니다 — 그렇지 않으면 Clerk 사용자 ID가 기존 외래 키(`orders.user_id`, `documents.owner_id` 등)와 전혀 일치하지 않게 되고, 과거 데이터가 사라진 것처럼 보이게 됩니다.

Replit이 관리하는 Clerk를 사용하면 이 작업이 간단해집니다. 사용자를 가져올 때 기존 ID를 Clerk 사용자의 `externalId`로 지정하면, 그 값은 자동으로 세션 클레임에 `sessionClaims.userId`로 기록됩니다. 미들웨어는 원본 Clerk 사용자 ID보다 이 값을 우선적으로 사용하기만 하면 됩니다.

```ts theme={null}
import { getAuth } from "@clerk/express";

const requireAuth = (req: any, res: any, next: any) => {
  const auth = getAuth(req);
  const userId = auth?.sessionClaims?.userId || auth?.userId;
  if (!userId) {
    return res.status(401).json({ error: "Unauthorized" });
  }
  req.userId = userId;
  next();
};
```

이 패턴을 사용하면:

* **가져온 사용자**는 `sessionClaims.userId`를 통해 기존 `users.id`로 매핑됩니다 — 모든 과거 데이터가 그대로 유지됩니다.
* **완전히 새로운 사용자**(전환 이후에 가입했고 `externalId`가 없는 사용자)는 `auth.userId`(그들의 Clerk 사용자 ID)로 대체됩니다. 이런 새 행에는 Clerk 사용자 ID를 기본 키로 사용하거나, 첫 로그인 시 행을 생성하고 다시 연결하세요.

## 이제 끝났습니다

그 외의 모든 것 — 기존 인증을 병렬로 계속 실행하기, 실제 계정을 대상으로 드라이런 실행하기, 전환 후 중복 사용자 생성 모니터링하기, 기존 시스템 폐기하기 — 는 표준적인 마이그레이션 위생 관리이며 Clerk Auth에만 특별히 해당되는 것은 아닙니다.

## 추가 자료

* [Clerk Auth 개요](/ko/features/auth-and-identity/clerk-auth) — Replit에서 Clerk Auth가 작동하는 방식
* [Clerk: Create User API](https://clerk.com/docs/reference/backend/user/create-user) — 지원되는 비밀번호 해셔와 다이제스트 형식
