Files
updater/LICENSE_SYSTEM.md

6.8 KiB

🎫 OneTake Updater - QR 라이선스 시스템

📋 개요

OneTake Updater는 JWT 서명 기반의 QR 코드 라이선스 시스템을 제공합니다.
프로젝트별로 라이선스를 발급하고, 만료일, 디바이스 제한, 연결 기기 수 등을 관리할 수 있습니다.


🔑 라이선스 구조

1. 라이선스 토큰 구성

라이선스는 Base64 인코딩된 JSON 형태로 발급됩니다:

{
  "d": "{라이선스 데이터 JSON}",
  "s": "{RSA-SHA256 서명 (Base64)}"
}

2. 라이선스 데이터 필드

필드 타입 설명 예시
expiry String 만료일 (YYYY-MM-DD) "2027-02-06"
deviceId String 허용된 디바이스 ID
(* = 모든 기기)
"ABC123" 또는 "*"
projectName String 프로젝트/카테고리 이름 "MYPROJECT"
tvLimit Integer 최대 연결 가능 기기 수
(0 = 무제한)
5
issuedAt Integer 발급 시각 (Unix timestamp, ms) 1738838400000
type String 라이선스 타입 "standard"

🎨 라이선스 발급 방법

포털에서 발급

  1. 관리자 로그인라이선스 발급 탭 이동
  2. 다음 정보 입력:
    • 만료일: 라이선스 유효 기간
    • 프로젝트 이름: 대분류 카테고리 선택 또는 직접 입력
    • Device ID: 특정 기기만 허용하려면 입력, 모든 기기 허용 시 *
    • 기기 연결 제한: 동시 연결 가능한 수신기(TV 등) 대수 (0 = 무제한)
  3. QR 생성하기 버튼 클릭
  4. QR 코드 모달 팝업 확인

발급 예시

만료일: 2027-12-31
프로젝트: MYPROJECT
Device ID: * (모든 기기)
연결 제한: 3대

생성된 토큰 예시:

eyJkIjoie1wiZXhwaXJ5XCI6XCIyMDI3LTEyLTMxXCIsXCJkZXZpY2VJZFwiOlwiKlwiLFwicHJvamVjdE5hbWVcIjpcIk1ZUFJPSkVDVFwiLFwidHZMaW1pdFwiOjMsXCJpc3N1ZWRBdFwiOjE3Mzg4Mzg0MDAwMDAsXCJ0eXBlXCI6XCJzdGFuZGFyZFwifSIsInMiOiJhYmMxMjMuLi4ifQ==

📤 라이선스 배포 방법

1. QR 코드 스캔 (권장)

  • 모바일 앱에서 QR 스캔 기능 구현
  • 스캔 즉시 토큰 문자열 획득

2. 카카오톡 공유

포털에서 "카카오톡으로 전송" 버튼 클릭 시:

  • QR 이미지와 함께 라이선스 정보 전송
  • 수신자가 QR 코드를 스캔하여 사용

카카오톡 메시지 구성:

[MYPROJECT] 라이선스 발급
📅 만료일: 2027-12-31
📱 연결제한: 3대

[QR 코드 이미지]

3. 텍스트 복사

  • QR 모달 하단의 토큰 문자열을 복사
  • 이메일, 메신저 등으로 전달
  • 수신자가 앱에 직접 붙여넣기

🔐 라이선스 검증 로직 (클라이언트 구현 가이드)

1. 토큰 파싱

// Base64 디코딩
const decoded = JSON.parse(atob(token));
const licenseData = JSON.parse(decoded.d);
const signature = atob(decoded.s);

2. 서명 검증 (RSA-SHA256)

// public_key.pem을 사용하여 서명 검증
const isValid = crypto.verify(
  'sha256',
  Buffer.from(decoded.d),
  publicKey,
  Buffer.from(signature)
);

3. 만료일 체크

const expiryDate = new Date(licenseData.expiry);
const now = new Date();

if (now > expiryDate) {
  throw new Error('라이선스가 만료되었습니다.');
}

4. 디바이스 ID 검증

const myDeviceId = getDeviceId(); // 기기 고유 ID 획득

if (licenseData.deviceId !== '*' && licenseData.deviceId !== myDeviceId) {
  throw new Error('이 기기에서 사용할 수 없는 라이선스입니다.');
}

5. 연결 제한 확인

const connectedDevices = getCurrentConnectedCount(); // 현재 연결된 기기 수

if (licenseData.tvLimit > 0 && connectedDevices >= licenseData.tvLimit) {
  throw new Error(`최대 ${licenseData.tvLimit}대까지 연결 가능합니다.`);
}

🛡️ 보안 고려사항

1. 키 관리

  • private_key.pem: 서버에만 보관, 절대 외부 유출 금지
  • public_key.pem: 클라이언트 앱에 포함 (검증용)

2. 토큰 저장

  • 클라이언트는 토큰을 안전한 저장소에 보관 (Keychain, EncryptedSharedPreferences 등)
  • 네트워크 전송 시 HTTPS 사용 필수

3. 재발급 정책

  • 만료된 라이선스는 재발급 필요
  • 분실 시 관리자가 새 토큰 발급

📊 사용 시나리오

시나리오 1: 단일 기기 라이선스

만료일: 2027-12-31
Device ID: DEVICE-ABC-123
연결 제한: 1대

→ 특정 태블릿 1대에서만 사용 가능, TV 1대 연결 가능

시나리오 2: 무제한 라이선스

만료일: 2099-12-31
Device ID: *
연결 제한: 0 (무제한)

→ 모든 기기에서 사용 가능, 연결 제한 없음

시나리오 3: 프로젝트 단위 라이선스

만료일: 2027-06-30
Device ID: *
프로젝트: COMPANY-A
연결 제한: 10대

→ COMPANY-A 프로젝트 전용, 최대 10대 TV 연결 가능


🔧 API 엔드포인트

라이선스 발급 (관리자 전용)

POST /index.php?action=gen_license
Content-Type: multipart/form-data

expiry=2027-12-31
deviceId=*
projectName=MYPROJECT
tvLimit=5

응답:

{
  "success": true,
  "token": "eyJkIjoie1wiZXhwaXJ5XCI6..."
}

QR 이미지 생성 (공개)

GET /index.php?action=qr_img&data={토큰}

→ QR 코드 PNG 이미지 반환 (외부 API 프록시)


📱 클라이언트 구현 체크리스트

  • QR 스캔 기능 구현
  • 토큰 파싱 로직 구현
  • RSA-SHA256 서명 검증 구현
  • 만료일 체크 로직 구현
  • 디바이스 ID 검증 로직 구현
  • 연결 제한 관리 로직 구현
  • 라이선스 갱신 알림 UI 구현
  • 에러 처리 및 사용자 안내 메시지 구현

🆘 FAQ

Q1. 라이선스가 만료되면 어떻게 되나요?

A. 앱이 실행되지 않거나 제한된 기능만 사용 가능합니다. 관리자에게 연락하여 새 라이선스를 발급받아야 합니다.

Q2. Device ID는 어떻게 확인하나요?

A. 앱 내 설정 화면에서 "기기 정보" 또는 "라이선스 정보"를 확인하면 표시됩니다.

Q3. 연결 제한을 초과하면?

A. 새로운 기기 연결 시 "최대 연결 대수 초과" 오류가 발생합니다. 기존 연결을 해제하거나 라이선스를 업그레이드해야 합니다.

Q4. 라이선스를 여러 명이 공유할 수 있나요?

A. Device ID가 *이고 연결 제한이 충분하다면 가능합니다. 단, 보안상 권장하지 않습니다.

Q5. 서명 검증이 실패하면?

A. 토큰이 위조되었거나 손상되었을 가능성이 있습니다. 관리자에게 재발급을 요청하세요.


📞 지원

라이선스 관련 문의: update@onetake.best
포털 접속: https://update.onetake.best