본문으로 건너뛰기

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
}
}

응답 필드:

필드타입설명
tierstring라이선스 등급 (Community, Professional, Enterprise)
expirationstring?만료일 (ISO 8601, null이면 무기한)
daysRemainingint남은 일수 (만료 시 0)
isValidbool유효성 여부
validationMessagestring검증 메시지
limits.maxTagsint최대 태그 수
limits.maxDriversint최대 드라이버 수
usage.currentTagsint현재 사용 중인 태그 수
usage.currentDriversint현재 사용 중인 드라이버 수

GET /hwid​

시스템의 하드웨어 ID를 조회합니다. 라이선스 발급 요청 시 필요합니다.

요청:

GET /api/license/hwid

응답 (200 OK):

{
"machineId": "A1B2C3D4E5F67890ABCDEF1234567890",
"maskedId": "A1B2****7890"
}

응답 필드:

필드타입설명
machineIdstring전체 하드웨어 ID (라이선스 발급 시 필요)
maskedIdstring마스킹된 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
}
]

응답 필드:

필드타입설명
timestampstring이벤트 발생 시각 (ISO 8601, UTC)
eventTypestring이벤트 유형 (Loaded, Validated, Expired, Failed)
messagestring이벤트 메시지
detailsstring?상세 정보 (선택)

POST /upload​

라이선스 토큰을 업로드하고 적용합니다.

요청:

POST /api/license/upload
Content-Type: application/json

{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

요청 필드:

필드타입필수설명
tokenstring✅라이선스 토큰 (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
}

응답 필드:

필드타입설명
successbool업로드 성공 여부
messagestring결과 메시지
licenseLicenseStatusDto?적용된 라이선스 정보 (성공 시)
토큰 자동 영속화 (v2.0.8+)

업로드 성공 시 토큰이 로컬 디스크에 자동 저장됩니다. 서버 재시작 시 저장된 토큰이 자동으로 로드되므로 재업로드가 필요 없습니다. 저장 경로는 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)​

등급최대 태그최대 드라이버기능
Community1002기본 모니터링
Professional1,00010고급 분석, 다중 사이트
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

v2.1.0 신규: AddCaffeineLicenseVerification()

Engine 외부에서 라이선스 검증만 필요한 경우 AddCaffeineLicenseVerification()을 사용하세요. ILicenseService와 IHardwareInfo만 등록되며, 라이선스 생성·서명 기능은 포함되지 않습니다.

builder.Services.AddCaffeineLicenseVerification();

자세한 내용: Infrastructure API — FIR-014

관련 문서​


네임스페이스: Caffeine.Engine.Controllers DTO 네임스페이스: Caffeine.Engine.DTOs 어셈블리: Caffeine.Engine.dll (v2.1.0) .NET 플랫폼: .NET 10.0