# Authentifizierung und Signierung

Weydub API-Anfragen verwenden die Header `AppKey` und `AppSign`. Bewahren Sie `AppSecret` ausschließlich serverseitig auf.

## Anfragestruktur

| Element | Wert |
| --- | --- |
| Basis-URL | `https://api.zhaoli.com` |
| Protokoll | HTTPS |
| Methode | `POST` für dokumentierte API-Aufrufe |
| Kodierung | UTF-8 |
| Inhaltstyp | `application/json` |
| Anfragekörper | JSON, für stabile Signaturen kompakt serialisiert |

## Header

```text
Content-Type: application/json
AppKey: your_app_key
AppSign: computed_signature
```

`AppSecret` wird niemals als Header oder als Feld im Anfragekörper gesendet. Es wird ausschließlich auf Ihrem Server verwendet, um `AppSign` zu berechnen.

## Signaturformel

```text
AppSign = md5(md5(request_body) + AppSecret)
```

Die Signatur muss aus dem exakten JSON-Anfragekörper berechnet werden, der über die Leitung gesendet wird. Für stabile Signaturen serialisieren Sie JSON ohne zusätzliche Leerzeichen.

Wenn ein Endpunkt einen leeren Anfragekörper zulässt, signieren Sie exakt die Bytes, die Sie senden. Bei den meisten Integrationen sollten Sie für Aufrufe ohne Anfragekörper vorzugsweise `{}` senden und `{}` signieren.

## Endpunkt ohne Signierung

Der Enum-Endpunkt erfordert keine Signierung:

```text
POST /v-w-c/enum/query2
```

Verwenden Sie ihn, um dynamische Sprach- und Status-Enums wie `sourceLang`, `Lang`, `ProcessStatus` und `ImageTaskStatus` abzurufen.

## Python-Hilfsfunktion für die Signierung

```python
import hashlib
import json


def signed_body_and_headers(payload: dict, app_key: str, app_secret: str):
    body = json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
    body_md5 = hashlib.md5(body.encode("utf-8")).hexdigest()
    app_sign = hashlib.md5((body_md5 + app_secret).encode("utf-8")).hexdigest()
    return body, {
        "Content-Type": "application/json",
        "AppKey": app_key,
        "AppSign": app_sign,
    }
```

## Node-Hilfsfunktion für die Signierung

```js
import crypto from "node:crypto";

export function signedBodyAndHeaders(payload, appKey, appSecret) {
  const body = JSON.stringify(payload);
  const bodyMd5 = crypto.createHash("md5").update(body).digest("hex");
  const appSign = crypto.createHash("md5").update(bodyMd5 + appSecret).digest("hex");
  return {
    body,
    headers: {
      "Content-Type": "application/json",
      AppKey: appKey,
      AppSign: appSign,
    },
  };
}
```

## cURL-Muster

Verwenden Sie Ihr Backend, um `AppSign` zu berechnen, und senden Sie anschließend exakt diesen Body:

```bash
curl -X POST "https://api.zhaoli.com/v-w-c/gateway/ve/work/status" \
  -H "Content-Type: application/json" \
  -H "AppKey: $WEYDUB_APP_KEY" \
  -H "AppSign: $WEYDUB_APP_SIGN" \
  --data '{"idWorks":[488026661]}'
```

## Callback-Signierung

Wenn Weydub einen Callback sendet, enthält dieser:

```text
Callback-Sign: computed_callback_signature
```

Überprüfen Sie Callbacks mit derselben Formel und verwenden Sie dabei den rohen Request-Body des Callbacks:

```text
expected = md5(md5(raw_callback_body) + AppSecret)
```

Vergleichen Sie `expected` mit `Callback-Sign`. Lehnen Sie Callback-Payloads ab oder stellen Sie sie unter Quarantäne, wenn die Überprüfung fehlschlägt.

## Häufige Fehler

- Lesbar formatiertes JSON signieren, aber kompaktes JSON senden.
- Den Payload nach dem Signieren verändern.
- Beim Signieren und Senden unterschiedliche Escape-Sequenzen für Zeichenketten verwenden.
- Ein Objekt im Arbeitsspeicher anstelle der endgültigen über HTTP gesendeten Bytes signieren.
- Übersehen, dass `extraOptions`, `wyVoiceParam`, `videoInpaintMasks`, `downloadInfo` und das Redo-`result` möglicherweise als kompakte JSON-Zeichenfolgen im äußeren JSON-Body verbleiben müssen.
- Anmeldedaten im Frontend-Code hinterlegen.
- `AppSecret` mit Browsererweiterungen, clientseitigen Apps, Screenshots, Protokollen oder öffentlichen Prompts teilen.

## Regeln für Agenten

- Anmeldedaten aus Umgebungsvariablen oder einem Secret-Manager lesen.
- `AppSecret` niemals ausgeben.
- Anmeldedaten niemals in generierte Beispieldateien schreiben.
- Beim Erstellen ausführbarer Beispiele Platzhalter oder Umgebungsvariablen verwenden.
- Bei der Fehlersuche nach einem Signaturfehler die Body-Bytes und nicht geheimen Body-Hashes vergleichen, ohne geheime Daten auszugeben.
- Bei Webhook-Handlern `Callback-Sign` verifizieren.
