Caffeine License API
Phase 20에서 도입된 Licensing 시스템의 REST API 엔드포인트입니다.
에디션별 기능·가격·활성화 절차는 **라이선스 & 가격 정책**을 참조하세요. 이 문서는 REST API 기술 사양만 다룹니다.
개요
License API는 라이선스 상태 조회, 하드웨어 ID 관리, 이력 추적, 토큰 업로드 기능을 제공합니다.
Base URL: http://localhost:5200/api/license
네임스페이스: Caffeine.Engine.Controllers
어셈블리: Caffeine.Engine.dll
.NET 버전: .NET 10.0
인증
현재 License API는 공개 엔드포인트입니다. 프로덕션 환경에서는 JWT Bearer 토큰 인증을 권장합니다.
Authorization: Bearer <token>
엔드포인트 요약
| 메서드 | 경로 | 설명 |
|---|---|---|
GET | /api/license/status | 라이선스 상태 조회 |
GET | /api/license/hwid | 하드웨어 ID 조회 |
GET | /api/license/features | 라이선스 기능 목록 조회 |
GET | /api/license/history | 라이선스 이력 조회 |
POST | /api/license/upload | 토큰 업로드 |
POST | /api/license/revalidate | 라이선스 재검증 |
상세 엔드포인트
GET /status
현재 라이선스 상태를 조회합니다.
요청:
GET /api/license/status
응답 (200 OK):
{
"tier": "Professional",
"expiration": "2026-12-31T23:59:59Z",
"daysRemaining": 329,
"isValid": true,
"validationMessage": "Valid license",
"limits": {
"maxTags": 1000,
"maxDrivers": 10
},
"usage": {
"currentTags": 50,
"currentDrivers": 3
}
}
응답 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
tier | string | 라이선스 등급 (Community, Professional, Enterprise) |
expiration | string? | 만료일 (ISO 8601, null이면 무기한) |
daysRemaining | int | 남은 일수 (만료 시 0) |
isValid | bool | 유효성 여부 |
validationMessage | string | 검증 메시지 |
limits.maxTags | int | 최대 태그 수 |
limits.maxDrivers | int | 최대 드라이버 수 |
usage.currentTags | int | 현재 사용 중인 태그 수 |
usage.currentDrivers | int | 현재 사용 중인 드라이버 수 |
GET /hwid
시스템의 하드웨어 ID를 조회합니다. 라이선스 발급 요청 시 필요합니다.
요청:
GET /api/license/hwid
응답 (200 OK):
{
"machineId": "A1B2C3D4E5F67890ABCDEF1234567890",
"maskedId": "A1B2****7890"
}
응답 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
machineId | string | 전체 하드웨어 ID (라이선스 발급 시 필요) |
maskedId | string | 마스킹된 ID (UI 표시용) |
GET /features
현재 라이선스에서 사용 가능한 기능 목록을 조회합니다.
요청:
GET /api/license/features
응답 (200 OK):
[
"BasicMonitoring",
"AdvancedAnalytics",
"MultiSiteSupport",
"CustomDrivers"
]
응답: 사용 가능한 기능명 문자열 배열
GET /history
라이선스 이벤트 이력을 조회합니다.
요청:
GET /api/license/history
응답 (200 OK):
[
{
"timestamp": "2026-02-06T10:30:00Z",
"eventType": "Loaded",
"message": "라이선스 로드 성공",
"details": "Tier: Professional"
},
{
"timestamp": "2026-02-05T14:00:00Z",
"eventType": "Validated",
"message": "라이선스 검증 완료",
"details": null
}
]
응답 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
timestamp | string | 이벤트 발생 시각 (ISO 8601, UTC) |
eventType | string | 이벤트 유형 (Loaded, Validated, Expired, Failed) |
message | string | 이벤트 메시지 |
details | string? | 상세 정보 (선택) |
POST /upload
라이선스 토큰을 업로드하고 적용합니다.
요청:
POST /api/license/upload
Content-Type: application/json
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
요청 필드:
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
token | string | ✅ | 라이선스 토큰 (JWT 형식) |
응답 (200 OK - 성공):
{
"success": true,
"message": "라이선스가 성공적으로 적용되었습니다.",
"license": {
"tier": "Professional",
"expiration": "2026-12-31T23:59:59Z",
"daysRemaining": 329,
"isValid": true,
"validationMessage": "Valid license",
"limits": {
"maxTags": 1000,
"maxDrivers": 10
},
"usage": {
"currentTags": 0,
"currentDrivers": 0
}
}
}
응답 (400 Bad Request - 실패):
{
"success": false,
"message": "라이선스 검증 실패: HWID mismatch",
"license": null
}
응답 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
success | bool | 업로드 성공 여부 |
message | string | 결과 메시지 |
license | LicenseStatusDto? | 적용된 라이선스 정보 (성공 시) |
업로드 성공 시 토큰이 로컬 디스크에 자동 저장됩니다. 서버 재시작 시 저장된 토큰이 자동으로 로드되므로 재업로드가 필요 없습니다. 저장 경로는 appsettings.json의 Licensing.TokenStorePath로 설정합니다.
POST /revalidate
현재 라이선스를 재검증합니다.
요청:
POST /api/license/revalidate
응답 (200 OK - 성공):
{
"tier": "Professional",
"expiration": "2026-12-31T23:59:59Z",
"daysRemaining": 329,
"isValid": true,
"validationMessage": "Valid license",
"limits": {
"maxTags": 1000,
"maxDrivers": 10
},
"usage": {
"currentTags": 50,
"currentDrivers": 3
}
}
응답 (400 Bad Request - 실패):
검증 실패 시에도 동일한 DTO 구조가 반환되며, isValid: false와 함께 validationMessage에 실패 사유가 포함됩니다.
DTO 정의
LicenseStatusDto
public class LicenseStatusDto
{
public string Tier { get; set; } = "Community";
public DateTime? Expiration { get; set; }
public int DaysRemaining { get; set; }
public bool IsValid { get; set; }
public string ValidationMessage { get; set; } = string.Empty;
public LicenseLimitsDto Limits { get; set; } = new();
public LicenseUsageDto Usage { get; set; } = new();
}
LicenseLimitsDto
public class LicenseLimitsDto
{
public int MaxTags { get; set; }
public int MaxDrivers { get; set; }
}
LicenseUsageDto
public class LicenseUsageDto
{
public int CurrentTags { get; set; }
public int CurrentDrivers { get; set; }
}
HardwareIdDto
public class HardwareIdDto
{
public string MachineId { get; set; } = string.Empty;
public string MaskedId { get; set; } = string.Empty;
}
LicenseUploadRequest
public class LicenseUploadRequest
{
public string Token { get; set; } = string.Empty;
}
LicenseUploadResponse
public class LicenseUploadResponse
{
public bool Success { get; set; }
public string Message { get; set; } = string.Empty;
public LicenseStatusDto? License { get; set; }
}
LicenseHistoryEventDto
public class LicenseHistoryEventDto
{
public DateTime Timestamp { get; set; }
public string EventType { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public string? Details { get; set; }
}
에러 코드
| HTTP 상태 | 설명 | 대응 방법 |
|---|---|---|
200 | 성공 | - |
400 | 잘못된 요청 (토큰 누락, 검증 실패) | 요청 본문 확인 |
401 | 인증 실패 (JWT 토큰 없음/만료) | 토큰 갱신 |
404 | 엔드포인트 없음 | URL 확인 |
500 | 서버 내부 오류 | 로그 확인 |
라이선스 등급 (Tier)
| 등급 | 최대 태그 | 최대 드라이버 | 기능 |
|---|---|---|---|
Community | 100 | 2 | 기본 모니터링 |
Professional | 1,000 | 10 | 고급 분석, 다중 사이트 |
Enterprise | 무제한 | 무제한 | 모든 기능, 기술 지원 |
전체 기능 비교는 에디션별 기능 비교를 참조하세요.
사용 예제
C# 예제
using System.Net.Http.Json;
var client = new HttpClient
{
BaseAddress = new Uri("http://localhost:5200")
};
// JWT 인증 (필요 시)
// client.DefaultRequestHeaders.Authorization =
// new AuthenticationHeaderValue("Bearer", token);
// 라이선스 상태 조회
var status = await client.GetFromJsonAsync<LicenseStatusDto>("/api/license/status");
Console.WriteLine($"Tier: {status?.Tier}");
Console.WriteLine($"Days Remaining: {status?.DaysRemaining}");
Console.WriteLine($"Valid: {status?.IsValid}");
// 하드웨어 ID 조회
var hwid = await client.GetFromJsonAsync<HardwareIdDto>("/api/license/hwid");
Console.WriteLine($"Machine ID: {hwid?.MachineId}");
// 토큰 업로드
var uploadResponse = await client.PostAsJsonAsync("/api/license/upload", new
{
Token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
});
var result = await uploadResponse.Content.ReadFromJsonAsync<LicenseUploadResponse>();
Console.WriteLine($"Upload Success: {result?.Success}");
Console.WriteLine($"Message: {result?.Message}");
curl 예제
# 라이선스 상태 조회
curl http://localhost:5200/api/license/status
# 하드웨어 ID 조회
curl http://localhost:5200/api/license/hwid
# 기능 목록 조회
curl http://localhost:5200/api/license/features
# 이력 조회
curl http://localhost:5200/api/license/history
# 토큰 업로드
curl -X POST http://localhost:5200/api/license/upload \
-H "Content-Type: application/json" \
-d '{"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}'
# 라이선스 재검증
curl -X POST http://localhost:5200/api/license/revalidate
PowerShell 예제
# 라이선스 상태 조회
$status = Invoke-RestMethod -Uri "http://localhost:5200/api/license/status"
Write-Host "Tier: $($status.tier)"
Write-Host "Valid: $($status.isValid)"
# 하드웨어 ID 조회
$hwid = Invoke-RestMethod -Uri "http://localhost:5200/api/license/hwid"
Write-Host "Machine ID: $($hwid.machineId)"
# 토큰 업로드
$body = @{ token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." } | ConvertTo-Json
$result = Invoke-RestMethod -Uri "http://localhost:5200/api/license/upload" `
-Method Post -Body $body -ContentType "application/json"
Write-Host "Success: $($result.success)"
Swagger UI
개발 환경에서 Swagger UI를 통해 API를 테스트할 수 있습니다:
http://localhost:5200/swagger
Engine 외부에서 라이선스 검증만 필요한 경우 AddCaffeineLicenseVerification()을 사용하세요. ILicenseService와 IHardwareInfo만 등록되며, 라이선스 생성·서명 기능은 포함되지 않습니다.
builder.Services.AddCaffeineLicenseVerification();
자세한 내용: Infrastructure API — FIR-014
관련 문서
- Caffeine.Core API - 핵심 모듈 API
- Caffeine.Client API - 클라이언트 SDK
- Caffeine.Infrastructure API - 인프라 서비스
- 설정 가이드 - 라이선스 설정 방법
네임스페이스: Caffeine.Engine.Controllers DTO 네임스페이스: Caffeine.Engine.DTOs 어셈블리: Caffeine.Engine.dll (v2.1.0) .NET 플랫폼: .NET 10.0