Merge pull request #1 from friloo/claude/unifi-api-migration-dbNMa
Migrate to UniFi OS API (port 11443)
This commit is contained in:
commit
a667b65180
3 changed files with 61 additions and 21 deletions
43
Readme.md
43
Readme.md
|
|
@ -34,7 +34,7 @@ Ein professionelles, webbasiertes System zur Verwaltung von WLAN-Vouchers für U
|
||||||
- JSON
|
- JSON
|
||||||
|
|
||||||
### UniFi Controller
|
### UniFi Controller
|
||||||
- UniFi Network Controller 6.0 oder höher
|
- UniFi Network Application 7.0+ mit UniFi OS (z.B. UDM, UDR, UniFi OS Server)
|
||||||
- API-Zugriff aktiviert
|
- API-Zugriff aktiviert
|
||||||
- Lokaler Admin-Account oder dedizierter API-User
|
- Lokaler Admin-Account oder dedizierter API-User
|
||||||
|
|
||||||
|
|
@ -43,8 +43,8 @@ Ein professionelles, webbasiertes System zur Verwaltung von WLAN-Vouchers für U
|
||||||
### Schritt 1: Dateien hochladen
|
### Schritt 1: Dateien hochladen
|
||||||
```bash
|
```bash
|
||||||
# Repository klonen oder ZIP herunterladen
|
# Repository klonen oder ZIP herunterladen
|
||||||
git clone https://github.com/ihr-username/unifi-voucher-system.git
|
git clone https://github.com/friloo/unifi-voucher-tool.git
|
||||||
cd unifi-voucher-system
|
cd unifi-voucher-tool
|
||||||
|
|
||||||
# Dateien auf den Webserver hochladen
|
# Dateien auf den Webserver hochladen
|
||||||
# Stellen Sie sicher, dass der Webserver-User Schreibrechte hat
|
# Stellen Sie sicher, dass der Webserver-User Schreibrechte hat
|
||||||
|
|
@ -131,7 +131,7 @@ rm install.php
|
||||||
3. Geben Sie folgende Daten ein:
|
3. Geben Sie folgende Daten ein:
|
||||||
- **Name**: Anzeigename (z.B. "Hauptgebäude")
|
- **Name**: Anzeigename (z.B. "Hauptgebäude")
|
||||||
- **Site ID**: UniFi Site ID (z.B. "default")
|
- **Site ID**: UniFi Site ID (z.B. "default")
|
||||||
- **Controller URL**: URL Ihres UniFi Controllers (z.B. "https://unifi.example.com:8443")
|
- **Controller URL**: URL Ihres UniFi Controllers (z.B. "https://unifi.example.com:11443")
|
||||||
- **Benutzername**: UniFi Admin-Username
|
- **Benutzername**: UniFi Admin-Username
|
||||||
- **Passwort**: UniFi Admin-Passwort
|
- **Passwort**: UniFi Admin-Passwort
|
||||||
- **Öffentlicher Zugriff**: Aktivieren für Login-freie Nutzung
|
- **Öffentlicher Zugriff**: Aktivieren für Login-freie Nutzung
|
||||||
|
|
@ -291,6 +291,13 @@ RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||||
- Stellen Sie sicher, dass cURL aktiviert ist
|
- Stellen Sie sicher, dass cURL aktiviert ist
|
||||||
- Prüfen Sie SSL-Zertifikate (CURLOPT_SSL_VERIFYPEER)
|
- Prüfen Sie SSL-Zertifikate (CURLOPT_SSL_VERIFYPEER)
|
||||||
|
|
||||||
|
**UniFi OS: Verbindung schlägt fehl (HTTP 404 oder 401):**
|
||||||
|
- Stellen Sie sicher, dass Sie Port 11443 verwenden (nicht 8443)
|
||||||
|
- UniFi OS erfordert den Pfad `/proxy/network/api/s/{site}/...` für alle API-Aufrufe
|
||||||
|
- Der Login-Endpunkt lautet `/api/auth/login` (nicht `/api/login`)
|
||||||
|
- Ältere UniFi Network Controller ohne UniFi OS werden ab Version 2.1.0 nicht mehr unterstützt
|
||||||
|
- Bei anhaltenden 401-Fehlern: Prüfen Sie, ob der UniFi-Account lokale API-Rechte besitzt
|
||||||
|
|
||||||
**Voucher werden nicht erstellt:**
|
**Voucher werden nicht erstellt:**
|
||||||
- Überprüfen Sie die UniFi Controller Logs
|
- Überprüfen Sie die UniFi Controller Logs
|
||||||
- Prüfen Sie API-Berechtigungen
|
- Prüfen Sie API-Berechtigungen
|
||||||
|
|
@ -333,17 +340,26 @@ cp -r /var/www/html/voucher /backup/voucher-$(date +%Y%m%d)
|
||||||
|
|
||||||
## 📝 API-Dokumentation
|
## 📝 API-Dokumentation
|
||||||
|
|
||||||
### UniFi Controller API Endpoints
|
### UniFi OS API Endpoints
|
||||||
|
|
||||||
|
> **Hinweis:** Ab Version 2.1.0 verwendet dieses Tool die UniFi OS API (Port 11443).
|
||||||
|
> Ältere Installationen mit dem klassischen UniFi Network Controller (Port 8443) müssen
|
||||||
|
> auf UniFi OS migrieren oder weiterhin Version 2.0.x verwenden.
|
||||||
|
|
||||||
**Login:**
|
**Login:**
|
||||||
```
|
```
|
||||||
POST /api/login
|
POST /api/auth/login
|
||||||
Body: {"username": "admin", "password": "password"}
|
Body: {"username": "admin", "password": "password"}
|
||||||
|
Response-Header: X-CSRF-Token: <token>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Der `X-CSRF-Token`-Wert aus dem Login-Response-Header wird automatisch extrahiert und
|
||||||
|
> bei allen nachfolgenden POST-Anfragen als `X-CSRF-Token`-Header mitgesendet.
|
||||||
|
|
||||||
**Voucher erstellen:**
|
**Voucher erstellen:**
|
||||||
```
|
```
|
||||||
POST /api/s/{site_id}/cmd/hotspot
|
POST /proxy/network/api/s/{site_id}/cmd/hotspot
|
||||||
|
Headers: X-CSRF-Token: <token>
|
||||||
Body: {
|
Body: {
|
||||||
"cmd": "create-voucher",
|
"cmd": "create-voucher",
|
||||||
"expire": 480,
|
"expire": 480,
|
||||||
|
|
@ -355,7 +371,14 @@ Body: {
|
||||||
|
|
||||||
**Vouchers abrufen:**
|
**Vouchers abrufen:**
|
||||||
```
|
```
|
||||||
GET /api/s/{site_id}/stat/voucher
|
GET /proxy/network/api/s/{site_id}/stat/voucher
|
||||||
|
```
|
||||||
|
|
||||||
|
**Voucher löschen:**
|
||||||
|
```
|
||||||
|
POST /proxy/network/api/s/{site_id}/cmd/hotspot
|
||||||
|
Headers: X-CSRF-Token: <token>
|
||||||
|
Body: {"cmd": "delete-voucher", "_id": "<voucher_id>"}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🤝 Mitwirken
|
## 🤝 Mitwirken
|
||||||
|
|
@ -402,5 +425,5 @@ Geplante Features:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Version:** 2.0.0
|
**Version:** 2.1.0
|
||||||
**Letztes Update:** Januar 2026
|
**Letztes Update:** April 2026
|
||||||
|
|
@ -532,9 +532,9 @@ $currentUser = $auth->getCurrentUser();
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="controller_url">Controller URL *</label>
|
<label for="controller_url">Controller URL *</label>
|
||||||
<input type="url" id="controller_url" name="controller_url" required
|
<input type="url" id="controller_url" name="controller_url" required
|
||||||
placeholder="https://unifi.example.com:8443">
|
placeholder="https://unifi.example.com:11443">
|
||||||
<small style="color: #999; font-size: 12px;">
|
<small style="color: #999; font-size: 12px;">
|
||||||
Vollständige URL inklusive Port (meist 8443)
|
Vollständige URL inklusive Port (meist 11443 für UniFi OS)
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ class UniFiController {
|
||||||
private $password;
|
private $password;
|
||||||
private $siteId;
|
private $siteId;
|
||||||
private $cookieFile;
|
private $cookieFile;
|
||||||
|
private $csrfToken = null;
|
||||||
|
|
||||||
public function __construct($controllerUrl, $username, $password, $siteId) {
|
public function __construct($controllerUrl, $username, $password, $siteId) {
|
||||||
$this->controllerUrl = rtrim($controllerUrl, '/');
|
$this->controllerUrl = rtrim($controllerUrl, '/');
|
||||||
|
|
@ -25,7 +26,7 @@ class UniFiController {
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
|
|
||||||
curl_setopt_array($ch, [
|
curl_setopt_array($ch, [
|
||||||
CURLOPT_URL => $this->controllerUrl . "/api/login",
|
CURLOPT_URL => $this->controllerUrl . "/api/auth/login",
|
||||||
CURLOPT_POST => true,
|
CURLOPT_POST => true,
|
||||||
CURLOPT_POSTFIELDS => json_encode([
|
CURLOPT_POSTFIELDS => json_encode([
|
||||||
'username' => $this->username,
|
'username' => $this->username,
|
||||||
|
|
@ -35,7 +36,18 @@ class UniFiController {
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
CURLOPT_SSL_VERIFYPEER => false,
|
||||||
CURLOPT_COOKIEJAR => $this->cookieFile,
|
CURLOPT_COOKIEJAR => $this->cookieFile,
|
||||||
CURLOPT_COOKIEFILE => $this->cookieFile,
|
CURLOPT_COOKIEFILE => $this->cookieFile,
|
||||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json']
|
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
|
||||||
|
CURLOPT_HEADERFUNCTION => function($ch, $header) {
|
||||||
|
$parts = explode(':', $header, 2);
|
||||||
|
if (count($parts) === 2) {
|
||||||
|
$name = trim($parts[0]);
|
||||||
|
$value = trim($parts[1]);
|
||||||
|
if (strtolower($name) === 'x-csrf-token') {
|
||||||
|
$this->csrfToken = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strlen($header);
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
@ -67,7 +79,12 @@ class UniFiController {
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
CURLOPT_SSL_VERIFYPEER => false,
|
||||||
CURLOPT_COOKIEFILE => $this->cookieFile,
|
CURLOPT_COOKIEFILE => $this->cookieFile,
|
||||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json']
|
CURLOPT_HTTPHEADER => array_filter([
|
||||||
|
'Content-Type: application/json',
|
||||||
|
($method === 'POST' && $this->csrfToken !== null)
|
||||||
|
? 'X-CSRF-Token: ' . $this->csrfToken
|
||||||
|
: null
|
||||||
|
])
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($method === 'POST' && $data !== null) {
|
if ($method === 'POST' && $data !== null) {
|
||||||
|
|
@ -103,7 +120,7 @@ class UniFiController {
|
||||||
'quota' => (int)$maxUses
|
'quota' => (int)$maxUses
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->apiRequest("/api/s/{$this->siteId}/cmd/hotspot", $data);
|
$response = $this->apiRequest("/proxy/network/api/s/{$this->siteId}/cmd/hotspot", $data);
|
||||||
|
|
||||||
if (!isset($response['data'][0]['create_time'])) {
|
if (!isset($response['data'][0]['create_time'])) {
|
||||||
throw new Exception("Voucher konnte nicht erstellt werden");
|
throw new Exception("Voucher konnte nicht erstellt werden");
|
||||||
|
|
@ -129,7 +146,7 @@ class UniFiController {
|
||||||
|
|
||||||
// Alle Voucher abrufen
|
// Alle Voucher abrufen
|
||||||
public function getVouchers() {
|
public function getVouchers() {
|
||||||
$response = $this->apiRequest("/api/s/{$this->siteId}/stat/voucher");
|
$response = $this->apiRequest("/proxy/network/api/s/{$this->siteId}/stat/voucher");
|
||||||
return $response['data'] ?? [];
|
return $response['data'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +213,7 @@ class UniFiController {
|
||||||
'_id' => $voucherId
|
'_id' => $voucherId
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->apiRequest("/api/s/{$this->siteId}/cmd/hotspot", $data);
|
$response = $this->apiRequest("/proxy/network/api/s/{$this->siteId}/cmd/hotspot", $data);
|
||||||
|
|
||||||
return isset($response['meta']['rc']) && $response['meta']['rc'] === 'ok';
|
return isset($response['meta']['rc']) && $response['meta']['rc'] === 'ok';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue