개발 slecs

라이선스 키 인증을 실계정 시스템으로 전면 전환

목차

라이선스 키 기반 로그인을 실계정(이메일+비밀번호+API 키) 시스템으로 완전히 바꿨다. 개발 초기에는 빠른 프로토타이핑을 위해 라이선스 키 하나로 모든 인증을 처리했는데, 서비스가 성장하면서 이 방식의 한계가 명확해졌다.

왜 이 변경이 필요했는가

라이선스 키 기반 시스템은 초기 MVP 단계에선 충분했다. 복잡한 사용자 관리 로직 없이 단순 문자열 검증만으로 접근 제어를 하니까 빨랐다. 하지만 실제 운영 환경으로 나가면서 여러 문제가 터졌다.

첫째, 개별 계정 관리가 불가능했다. 누가 어떤 권한으로 접근했는지 추적할 수 없고, 특정 사용자의 접근을 차단하거나 권한을 세분화할 방법이 없었다. 둘째, 보안 감사에서 문제가 됐다. 라이선스 키는 공유되거나 유출되기 쉬운데, 실제 비밀번호 기반 인증이라면 훨씬 더 세밀한 감사 로그와 재발급 정책을 적용할 수 있다. 셋째, API 접근과 웹 로그인의 구분이 필요했다. 과거 방식은 단일 라이선스 키로 모든 채널을 처리했는데, API 클라이언트와 사람이 웹 인터페이스로 접근하는 방식을 다르게 다뤄야 했다.

실제 구현의 변화

변경된 파일들을 보면 전체 아키텍처의 물갈이가 일어났다는 걸 알 수 있다.

계층 역할 변화
domain/polar-config.ts 라이선스 키 스키마 → 실계정(이메일, 비밀번호) 스키마로 변경
infrastructure/account-store.ts 신규. 사용자 계정의 저장/조회/검증 담당
infrastructure/license-store.ts 레거시. 라이선스 키 저장소(점진적 제거 대기)
application/entitlement.ts 권한 검증 로직. 라이선스 기반 → 계정 기반 조회로 변경

account-store.ts 같은 새로운 저장소가 생긴 것을 보면, 단순한 필드 추가가 아니라 전체 데이터 접근 패턴의 전환을 했다는 뜻이다.

// 예상되는 변경 방향
// Before: 라이선스 키 문자열 하나로 모든 접근 검증
const isValid = licenseStore.validateKey(keyString);

// After: 이메일+비밀번호로 계정 조회 → 권한 확인
const account = accountStore.findByEmail(email);
const isPasswordValid = await account.verifyPassword(password);
const entitlements = await entitlementService.getByAccount(account.id);

팀 관점에서의 영향

이런 규모의 변경은 단순 코드 수정이 아니라 전체 팀의 멘탈 모델 변화를 의미한다.

  • 온보딩 복잡도 증가: 새 팀원이 라이선스 키 시스템만 이해해도 됐는데, 이제 계정 관리, 비밀번호 해싱, API 키 발급 등 여러 도메인을 이해해야 한다. 대신 실제 서비스처럼 동작하니까 더 쉽게 배울 수도 있다.

  • 마이그레이션 어려움: package.json 변경(의존성 추가/제거)에서 보이듯이, 인증 관련 라이브러리(bcrypt 같은 비밀번호 해싱 도구)가 추가됐을 것 같다. 기존 라이센스 키로 접근하던 클라이언트들도 업데이트해야 한다.

  • QA 범위 확대: 라이선스 키는 단순 문자열 매칭이라 테스트가 가볍지만, 실계정 시스템은 비밀번호 재설정, 계정 잠금, API 키 갱신 등 훨씬 많은 시나리오를 테스트해야 한다.

배운 점과 회고

이 작업을 보면서 느낀 것은, 프로토타입 로직을 프로덕션으로 그냥 끌고 가면 나중에 큰 리팩토링 비용이 든다는 것이다. 초기에 "일단 빠르게 만들자"는 결정이 맞았다고 해도, 그 시점에 "3개월 뒤엔 이걸 갈아엎어야 할 거다"라는 가정을 문서화하고 팀과 공유하는 게 중요하다.

또한 license-store.tsaccount-store.ts가 동시에 존재하는 구조를 보면, 아마 점진적 마이그레이션 전략을 썼을 것 같다. 모든 요청을 한 번에 바꾸는 게 아니라, 신규 사용자는 실계정, 기존 라이선스 키 사용자는 호환 레이어를 통해 순차적으로 전환하는 방식. 이건 서비스 중단 없이 큰 변경을 하는 전형적인 패턴이다.

마지막으로 이 변경이 단순 기술 개선이 아니라 보안과 감사 추적성을 동시에 확보하는 비즈니스 결정이었다는 점을 기억해두자. "왜 이렇게 복잡하게?"라고 느낄 때마다, "고객 데이터 보호"와 "규제 준수"가 그 답이 될 수 있다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.