lizenzserver
Dieser Commit ist enthalten in:
335
v2_lizenzserver/LIZENZSERVER_ANLEITUNG.md
Normale Datei
335
v2_lizenzserver/LIZENZSERVER_ANLEITUNG.md
Normale Datei
@@ -0,0 +1,335 @@
|
||||
# Lizenzserver Nutzungsanleitung
|
||||
|
||||
## Übersicht
|
||||
Der Lizenzserver läuft unter: `https://api-software-undso.z5m7q9dk3ah2v1plx6ju.com`
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Lizenz aktivieren
|
||||
**POST** `/api/license/activate`
|
||||
|
||||
Aktiviert eine Lizenz für eine bestimmte Maschine.
|
||||
|
||||
```json
|
||||
{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"machine_id": "UNIQUE-MACHINE-ID",
|
||||
"hardware_hash": "SHA256-HARDWARE-FINGERPRINT",
|
||||
"os_info": {
|
||||
"os": "Windows",
|
||||
"version": "10.0.19041"
|
||||
},
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**Antwort bei Erfolg:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "License activated successfully",
|
||||
"activation_id": 123,
|
||||
"expires_at": "2025-12-31T23:59:59",
|
||||
"features": {
|
||||
"all_features": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Lizenz verifizieren (Heartbeat)
|
||||
**POST** `/api/license/verify`
|
||||
|
||||
Sollte alle 15 Minuten aufgerufen werden.
|
||||
|
||||
```json
|
||||
{
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX",
|
||||
"machine_id": "UNIQUE-MACHINE-ID",
|
||||
"hardware_hash": "SHA256-HARDWARE-FINGERPRINT",
|
||||
"activation_id": 123
|
||||
}
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"valid": true,
|
||||
"message": "License is valid",
|
||||
"expires_at": "2025-12-31T23:59:59",
|
||||
"features": {
|
||||
"all_features": true
|
||||
},
|
||||
"requires_update": false,
|
||||
"update_url": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Version prüfen
|
||||
**POST** `/api/version/check`
|
||||
|
||||
```json
|
||||
{
|
||||
"current_version": "1.0.0",
|
||||
"license_key": "XXXX-XXXX-XXXX-XXXX"
|
||||
}
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"latest_version": "1.1.0",
|
||||
"current_version": "1.0.0",
|
||||
"update_available": true,
|
||||
"is_mandatory": false,
|
||||
"download_url": "https://download.example.com/v1.1.0",
|
||||
"release_notes": "Bug fixes and improvements"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Lizenzinfo abrufen
|
||||
**GET** `/api/license/info/{license_key}`
|
||||
|
||||
Liefert detaillierte Informationen über eine Lizenz.
|
||||
|
||||
## Authentifizierung
|
||||
|
||||
Alle API-Anfragen benötigen einen API-Key im Authorization Header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR-API-KEY-HERE
|
||||
```
|
||||
|
||||
## Client-Integration Beispiel (Python)
|
||||
|
||||
```python
|
||||
import requests
|
||||
import hashlib
|
||||
import platform
|
||||
import uuid
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class LicenseClient:
|
||||
def __init__(self, api_key, server_url="https://api-software-undso.z5m7q9dk3ah2v1plx6ju.com"):
|
||||
self.api_key = api_key
|
||||
self.server_url = server_url
|
||||
self.headers = {"Authorization": f"Bearer {api_key}"}
|
||||
|
||||
def get_machine_id(self):
|
||||
"""Eindeutige Maschinen-ID generieren"""
|
||||
return str(uuid.getnode()) # MAC-Adresse
|
||||
|
||||
def get_hardware_hash(self):
|
||||
"""Hardware-Fingerprint erstellen"""
|
||||
machine_id = self.get_machine_id()
|
||||
cpu_info = platform.processor()
|
||||
system_info = f"{platform.system()}-{platform.machine()}"
|
||||
|
||||
combined = f"{machine_id}-{cpu_info}-{system_info}"
|
||||
return hashlib.sha256(combined.encode()).hexdigest()
|
||||
|
||||
def activate_license(self, license_key):
|
||||
"""Lizenz aktivieren"""
|
||||
data = {
|
||||
"license_key": license_key,
|
||||
"machine_id": self.get_machine_id(),
|
||||
"hardware_hash": self.get_hardware_hash(),
|
||||
"os_info": {
|
||||
"os": platform.system(),
|
||||
"version": platform.version(),
|
||||
"machine": platform.machine()
|
||||
},
|
||||
"app_version": "1.0.0"
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
f"{self.server_url}/api/license/activate",
|
||||
headers=self.headers,
|
||||
json=data,
|
||||
verify=True # SSL-Zertifikat prüfen
|
||||
)
|
||||
|
||||
return response.json()
|
||||
|
||||
def verify_license(self, license_key, activation_id):
|
||||
"""Lizenz verifizieren (Heartbeat)"""
|
||||
data = {
|
||||
"license_key": license_key,
|
||||
"machine_id": self.get_machine_id(),
|
||||
"hardware_hash": self.get_hardware_hash(),
|
||||
"activation_id": activation_id
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
f"{self.server_url}/api/license/verify",
|
||||
headers=self.headers,
|
||||
json=data,
|
||||
verify=True
|
||||
)
|
||||
|
||||
return response.json()
|
||||
|
||||
def check_version(self, license_key, current_version):
|
||||
"""Version prüfen"""
|
||||
data = {
|
||||
"current_version": current_version,
|
||||
"license_key": license_key
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
f"{self.server_url}/api/version/check",
|
||||
headers=self.headers,
|
||||
json=data,
|
||||
verify=True
|
||||
)
|
||||
|
||||
return response.json()
|
||||
|
||||
# Verwendungsbeispiel
|
||||
if __name__ == "__main__":
|
||||
client = LicenseClient("YOUR-API-KEY")
|
||||
|
||||
# Lizenz aktivieren
|
||||
result = client.activate_license("USER-LICENSE-KEY")
|
||||
if result["success"]:
|
||||
activation_id = result["activation_id"]
|
||||
print(f"Lizenz aktiviert! Activation ID: {activation_id}")
|
||||
|
||||
# Lizenz verifizieren
|
||||
verify_result = client.verify_license("USER-LICENSE-KEY", activation_id)
|
||||
if verify_result["valid"]:
|
||||
print("Lizenz ist gültig!")
|
||||
```
|
||||
|
||||
## Client-Integration Beispiel (C#)
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
using System.Management;
|
||||
|
||||
public class LicenseClient
|
||||
{
|
||||
private readonly HttpClient httpClient;
|
||||
private readonly string apiKey;
|
||||
private readonly string serverUrl;
|
||||
|
||||
public LicenseClient(string apiKey, string serverUrl = "https://api-software-undso.z5m7q9dk3ah2v1plx6ju.com")
|
||||
{
|
||||
this.apiKey = apiKey;
|
||||
this.serverUrl = serverUrl;
|
||||
|
||||
httpClient = new HttpClient();
|
||||
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
|
||||
}
|
||||
|
||||
private string GetMachineId()
|
||||
{
|
||||
// CPU ID abrufen
|
||||
string cpuId = "";
|
||||
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor");
|
||||
foreach (ManagementObject obj in searcher.Get())
|
||||
{
|
||||
cpuId = obj["ProcessorId"].ToString();
|
||||
break;
|
||||
}
|
||||
return cpuId;
|
||||
}
|
||||
|
||||
private string GetHardwareHash()
|
||||
{
|
||||
string machineId = GetMachineId();
|
||||
string systemInfo = Environment.MachineName + Environment.OSVersion;
|
||||
|
||||
using (SHA256 sha256 = SHA256.Create())
|
||||
{
|
||||
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(machineId + systemInfo));
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LicenseActivationResponse> ActivateLicenseAsync(string licenseKey)
|
||||
{
|
||||
var requestData = new
|
||||
{
|
||||
license_key = licenseKey,
|
||||
machine_id = GetMachineId(),
|
||||
hardware_hash = GetHardwareHash(),
|
||||
os_info = new
|
||||
{
|
||||
os = "Windows",
|
||||
version = Environment.OSVersion.Version.ToString()
|
||||
},
|
||||
app_version = "1.0.0"
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(requestData);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await httpClient.PostAsync($"{serverUrl}/api/license/activate", content);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return JsonSerializer.Deserialize<LicenseActivationResponse>(responseContent);
|
||||
}
|
||||
}
|
||||
|
||||
public class LicenseActivationResponse
|
||||
{
|
||||
public bool success { get; set; }
|
||||
public string message { get; set; }
|
||||
public int? activation_id { get; set; }
|
||||
public DateTime? expires_at { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## Wichtige Hinweise
|
||||
|
||||
### Sicherheit
|
||||
- API-Keys niemals im Quellcode hartcodieren
|
||||
- SSL-Zertifikat immer prüfen (verify=True)
|
||||
- Hardware-Hash lokal zwischenspeichern
|
||||
|
||||
### Rate Limiting
|
||||
- Max. 100 Anfragen pro Minute pro API-Key
|
||||
- Heartbeat alle 15 Minuten (nicht öfter)
|
||||
|
||||
### Offline-Betrieb
|
||||
- 7 Tage Grace Period bei Verbindungsproblemen
|
||||
- Letzte gültige Lizenz lokal cachen
|
||||
- Bei Hardware-Änderung: Grace Period nutzen
|
||||
|
||||
### Fehlerbehandlung
|
||||
```python
|
||||
try:
|
||||
result = client.verify_license(license_key, activation_id)
|
||||
except requests.exceptions.ConnectionError:
|
||||
# Offline-Modus: Gecachte Lizenz prüfen
|
||||
if cached_license_valid():
|
||||
continue_execution()
|
||||
else:
|
||||
show_error("Keine Internetverbindung und Lizenz abgelaufen")
|
||||
except requests.exceptions.HTTPError as e:
|
||||
if e.response.status_code == 401:
|
||||
show_error("Ungültiger API-Key")
|
||||
elif e.response.status_code == 403:
|
||||
show_error("Lizenz ungültig oder abgelaufen")
|
||||
```
|
||||
|
||||
## Test-Zugangsdaten
|
||||
|
||||
Für Entwicklungszwecke:
|
||||
- Test API-Key: `test-api-key-12345`
|
||||
- Test Lizenz: `TEST-LICENSE-KEY-12345`
|
||||
|
||||
**WICHTIG:** Für Produktion eigene API-Keys und Lizenzen erstellen!
|
||||
|
||||
## Support
|
||||
|
||||
Bei Problemen:
|
||||
1. Logs prüfen: `docker logs license-server`
|
||||
2. API-Status: https://api-software-undso.z5m7q9dk3ah2v1plx6ju.com/health
|
||||
3. Datenbank prüfen: Lizenzen und Aktivierungen
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren