Captcha-API-Schlüssel für Ihre Kunden bereitstellen

Wenn Sie CapSkip für andere betreiben, können Sie Captcha-API-Schlüssel in dem Moment bereitstellen, in dem ein Kunde bezahlt, direkt aus Ihrem Billing-Webhook heraus. Remote Key Management stellt drei POST-Endpunkte bereit, die Schlüssel auf der laufenden Instanz anlegen, auflisten und löschen, und ein neuer Schlüssel gilt schon bei der nächsten Anfrage zum Captcha-Lösen. Kein Neustart, kein manueller Schritt, und zwischen einer bestätigten Zahlung und einem Kunden, der loslegen kann, steht nichts mehr. Dieser Beitrag zeigt, wie Sie beim Abschluss einen Schlüssel anlegen, ihn bei der Kündigung entziehen, Ihre Schlüsselliste mit dem Billing abgleichen und welchen Netzwerkfehler dieses Setup besonders leicht macht.
Was Sie brauchen
- CapSkip läuft auf einem Windows-Rechner, über den Sie verfügen. Dieser Rechner ist Ihr Lösungsdienst und der einzige, auf dem die Anwendung überhaupt installiert sein muss. Ihre Kunden installieren gar nichts.
- Der Server-Modus, damit diese Kunden die Instanz auch wirklich erreichen. Der Local-Modus lauscht auf der Loopback-Adresse und bedient nur dieses eine Gerät, während der Server-Modus auf Ihrer Netzwerk- oder öffentlichen IP lauscht, sodass andere Rechner eine Verbindung aufbauen können. Beide Modi sind beschrieben unter Verbindungseinstellungen, und eine statische öffentliche IP sollten Sie haben, bevor Sie die Adresse herausgeben.
- Ein einziger Besuch im CapSkip-Fenster, um den Admin-token zu erzeugen. Das ist der einzige Schritt, der in der Oberfläche stattfindet, und Sie wiederholen ihn nie.
- Ein Ort, von dem aus Sie die Aufrufe absetzen: Ihr Billing-Webhook-Handler, das Backend Ihres Dashboards oder ein Terminal, solange Sie testen.
Eines gehört vor dem Code klar gesagt, weil genau daran dieses Modell hängt. Die Schlüssel, die Sie ausgeben, prägen Sie selbst. Es sind keine gekauften Guthaben, die Sie weiterverkaufen, und dahinter steckt keine Abrechnung pro Lösung. CapSkip läuft auf Ihrer Hardware, hundert Kundenschlüssel kosten also genau so viel wie einer.
Schritt 1: Remote Key Management einschalten
Der Schalter sitzt in Settings, unter API Key Validation, dann Advanced, dann Remote Key Management. Schalten Sie ihn ein und drücken Sie die Schaltfläche Generate.
Der token wird genau einmal angezeigt und nur als gesalzener Hash gespeichert, später lässt er sich also nirgends mehr auslesen. Ist er weg, erzeugen Sie einen neuen, und der alte verliert sofort seine Gültigkeit. Betrachten Sie das als Ihren Widerrufsknopf, denn einen eigenen gibt es nicht. Legen Sie ihn dorthin, wo Ihr Billing seine übrigen Geheimnisse hält, und nicht in Ihren Anwendungscode.
Die Endpunkte liegen auf demselben Host und Port, der Ihre Anfragen zum Lösen ohnehin schon beantwortet. Sprechen Ihre Kunden Port 8080 an, dann liegt dort auch die Admin-API. Das ist bequem, und genau damit müssen Sie vorsichtig sein: dazu weiter unten ein eigener Abschnitt.
Solange die Funktion aus ist, liefert jeder Admin-Pfad einen nackten 404 ohne Body. Genau dieselbe Antwort bekommt ein unbekannter Pfad, und das ist Absicht: Wer den Port abklopft, kann eine Instanz mit abgeschalteter Funktion nicht von einer unterscheiden, die diese Funktion gar nicht kennt.
Schritt 2: einen Schlüssel anlegen, sobald ein Kunde abschließt
Alle drei Endpunkte sind POST, nehmen einen JSON-Body entgegen und verlangen einen Authorization-Header, der den token als Bearer-Credential trägt. Der Anlege-Aufruf braucht einen Namen. Übergeben Sie nur den Namen und lassen Sie CapSkip den Wert erzeugen, was hier genau richtig ist: Der Kunde soll sich sein Credential nicht selbst aussuchen.
# No install needed. Name the key after the customer, not after the plan.
curl -X POST http://YOUR_SERVER:8080/admin/keys/add \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{"name":"cust_10482"}'
# Response carries the value to show the customer once:
# {"errorId":0,"key":{"name":"cust_10482","key":"..."}}Benennen Sie ihn nach etwas Stabilem aus Ihrem eigenen System, etwa der Kunden- oder der Abonnement-ID. Namen sind eindeutig, und die Regel wird beim Anlegen durchgesetzt, der Name wird damit zum verlässlichen Griff für jede spätere Operation. Schlüssel stattdessen nach Tarif oder Datum zu benennen ist der Fehler, der den Kündigungstag schmerzhaft macht.
Diese Eindeutigkeitsregel ist zugleich Ihr Schutz gegen Doppelverarbeitung. Zahlungsanbieter senden Webhooks erneut, und ein wiederholtes Abschluss-Ereignis kommt als 409 mit ERROR_KEY_EXISTS zurück, statt still einen zweiten Schlüssel für denselben Kunden anzulegen. Behandeln Sie diesen 409 in Ihrem Handler als Erfolg, dann ist das Wiederholungsproblem erledigt.
Der Wert kommt genau einmal zurück, in eben dieser Antwort. Zeigen Sie ihn dem Kunden oder speichern Sie ihn dort, wo Ihr Dashboard liest, denn das spätere Auflisten der Schlüssel ist eine Admin-Operation und nichts, was Sie ausführen wollen, um ein einzelnes Credential wiederzubeschaffen.
Schritt 3: den Schlüssel bei der Kündigung entziehen
Das Löschen nimmt genau ein Merkmal entgegen, entweder den Wert oder den Namen. Da Sie nach Kunden benannt haben, ist der Name die richtige Wahl:
# By name, which is unambiguous because names are unique.
curl -X POST http://YOUR_SERVER:8080/admin/keys/delete \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{"name":"cust_10482"}'
# By value works too, if that is what your records hold:
# -d '{"key":"the-old-value"}'Der Entzug greift ab der nächsten Anfrage zum Lösen, der Zugang endet also in dem Moment, in dem der Aufruf zurückkehrt. Von da an scheitern die Aufrufe dieses Kunden mit ERROR_KEY_DOES_NOT_EXIST, und das ist ein klares Signal: Die Integration kann es als abgelaufenes Abonnement ausweisen statt als Störung.
Entscheiden Sie bewusst, wann Sie das auslösen. Beim Kündigungs-Ereignis zu löschen kappt den Zugang sofort, obwohl der Kunde meist bis zum Periodenende bezahlt hat. Beim Periodenende zu löschen ist das, was die meisten tatsächlich wollen. Eine fehlgeschlagene Zahlung ist der dritte Fall: eine kurze Kulanzfrist vor dem Entzug erzeugt weit weniger Support-Tickets als ein Schlüssel, der bei einem erneuten Abbuchungsversuch verschwindet.
Schritt 4: die Liste mit Ihrem Billing abgleichen
Der Listenaufruf nimmt ein leeres Objekt und gibt jeden Schlüssel zurück, den die Instanz derzeit akzeptiert.
# The audit: exactly who can solve right now.
curl -X POST http://YOUR_SERVER:8080/admin/keys/list \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" -d '{}'{
"errorId": 0,
"keys": [
{ "name": "cust_10482", "key": "..." },
{ "name": "cust_10515", "key": "..." }
]
}Eine errorId von 0 bedeutet Erfolg, dieselbe Konvention nutzen auch die Endpunkte zum Lösen. Lassen Sie das nach Zeitplan laufen und gleichen Sie die Namen mit Ihren aktiven Abonnements ab. Ein Schlüssel ohne passendes Abonnement bedeutet, dass jemand weiterhin kostenlos löst, und ein Abonnement ohne Schlüssel bedeutet einen Kunden, dessen Bereitstellungs-Webhook verloren ging und der vermutlich gleich ein Ticket öffnet. Beides bleibt still, bis Sie hinsehen, und dieser Aufruf ist der einzige Ort, an dem die Wahrheit steht.
Der Einbau in einen Abonnement-Webhook
Zusammengesetzt besteht die ganze Integration aus zwei Handlern und einer Idempotenzregel:
# pip install requests
import requests
BASE = "http://YOUR_SERVER:8080"
AUTH = {"Authorization": "Bearer YOUR_TOKEN"}
def admin(path, body):
r = requests.post(f"{BASE}/admin/keys/{path}", json=body,
headers=AUTH, timeout=10)
# 409 on add means the key already exists, which is what a
# retried webhook looks like. Treat it as success, not failure.
if r.status_code == 409:
return None
r.raise_for_status()
return r.json()
def on_subscription_active(customer_id):
created = admin("add", {"name": f"cust_{customer_id}"})
return created["key"]["key"] if created else None
def on_subscription_ended(customer_id):
admin("delete", {"name": f"cust_{customer_id}"})Behandeln Sie das None aus einem wiederholten Abschluss bewusst. Es bedeutet, dass der Schlüssel existiert, Sie seinen Wert aber nicht mehr sehen können. Haben Sie ihn beim ersten Mal nicht gespeichert, führt der Weg über Löschen und neu Anlegen, nicht über das Auflisten. Speichern Sie den Wert gleich beim ersten Empfang, dann entsteht die Situation gar nicht erst.
Lassen Sie die Admin-API nicht auf dem Port liegen, den Kunden sehen
Für dieses Setup ist das der wichtigste Abschnitt, denn die Bequemlichkeit von einem Host und einem Port schneidet in beide Richtungen. Ihre Kunden müssen die Endpunkte zum Lösen erreichen. Die Admin-Endpunkte liegen auf demselben Port, geschützt allein durch den Bearer token, und eine Transportprüfung gibt es nicht, auf einem eigenen Port geht dieser token also im Klartext über HTTP. Wer diesen Verkehr mitlesen kann, liest ihn, und wer ihn besitzt, legt sich selbst einen Schlüssel an.
Setzen Sie einen Reverse Proxy vor die Instanz und trennen Sie die beiden Zielgruppen:
- Veröffentlichen Sie im Internet nur die Pfade zum Lösen, über HTTPS mit Terminierung am Proxy, und geben Sie für alles unterhalb des Admin-Pfads einen 404 zurück.
- Erreichen Sie die Admin-Endpunkte von Ihrem eigenen Backend über einen privaten Weg: über die Loopback-Adresse, wenn Ihr Billing auf demselben Windows-Rechner läuft, sonst über ein privates Netz, ein VPN oder einen SSH-Tunnel.
Die Faustregel lautet: Der Admin-token darf Ihre Infrastruktur nie verlassen, und der Port, mit dem er spricht, darf nie einer sein, den ein Kunde erreicht. Geben Sie den Admin-Pfad niemals ins offene Internet, ob die Funktion nun eingeschaltet ist oder nicht.
Eine weitere Grenze ist wissenswert, denn ein Kundenportal ist hier das Naheliegendste, was man bauen will. Browser können diese Endpunkte nicht aufrufen, denn Admin-Antworten senden bewusst keine CORS -Header. Ihr Dashboard muss über Ihr eigenes Backend laufen, und genau dorthin gehört der token ohnehin.
Wohin die Schlüssel tatsächlich geschrieben werden
Die Schlüssel landen dort, wo Ihre Schlüssel ohnehin liegen. Direct Input und From File sind zwei getrennte Listen, und die API liest und schreibt jeweils die gerade ausgewählte. Wechseln Sie die Quelle im Einstellungsfenster, ändert sich auch, was die Endpunkte sehen. Vergewissern Sie sich also erst, in welchem Modus Sie sind, bevor Sie sich wundern, warum ein eben bereitgestellter Schlüssel nicht in der Liste steht.
Beim Dateimodus lohnt sich ein Hinweis vorab: Der erste Schreibvorgang schreibt eine Klartext-Schlüsseldatei als JSON neu. Es geht nichts verloren, aber das Format ändert sich dauerhaft, sichern Sie die Datei also vorher, falls noch etwas anderes sie liest. Ist überhaupt keine Datei ausgewählt, kann ein Schreibvorgang nirgends landen und Sie bekommen ERROR_ADMIN_STORE_FAILURE mit einem 500. Fast immer bedeutet ein 500 an dieser Stelle genau das.
Listen, die es schon vor dieser Funktion gab, können weiterhin doppelte Namen enthalten, weil die Eindeutigkeit nur beim Anlegen geprüft wird. Ein Löschen per Name trifft dort auf ERROR_KEY_NAME_AMBIGUOUS und ändert nichts. Löschen Sie stattdessen über den Wert, dann ist die Mehrdeutigkeit weg.
Anführungszeichen in der Windows-Shell, falls Sie direkt auf dem Rechner testen
CapSkip ist eine Windows-Anwendung, der Rechner, von dem aus Sie testen, läuft also oft ebenfalls unter Windows. Die Eingabeaufforderung behandelt das einfache Anführungszeichen nicht als Anführungszeichen. Der kopierte Befehl schickt die Zeichen als Teil des JSON-Bodys mit, der Parser lehnt ab, und Sie bekommen ERROR_ADMIN_BAD_REQUEST bei einem Befehl, der völlig korrekt aussieht.
| Shell | Leerer Text | Mit Feldern |
|---|---|---|
| Eingabeaufforderung | -d "{}" | -d "{\"name\":\"prod\"}" |
| PowerShell, mit curl.exe | -d '{}' | -d '{\"name\":\"prod\"}' |
| Git Bash, macOS, Linux | -d '{}' | -d '{"name":"prod"}' |
Rufen Sie curl.exe in PowerShell mit vollem Namen auf. Das schlichte curl ist dort ein Alias für Invoke-WebRequest, das ganz andere Argumente erwartet und auf eine Weise scheitert, die mit dieser API nichts zu tun hat.
Fehlercodes
| Status | Code | Ursache |
|---|---|---|
| 404 | Klartext | Funktion aus oder Pfad unbekannt. Bewusst nicht unterscheidbar. |
| 401 | ERROR_ADMIN_UNAUTHORIZED | Token fehlt, ist fehlerhaft oder falsch. |
| 405 | ERROR_ADMIN_METHOD_NOT_ALLOWED | Sie haben etwas anderes als ein POST gesendet. |
| 400 | ERROR_ADMIN_BAD_REQUEST | Der Body ist kein gültiges JSON, beim Anlegen fehlt der Name, oder beim Löschen sind beide Merkmale oder keines gesetzt. |
| 409 | ERROR_KEY_EXISTS | Dieser Name oder dieser Wert ist bereits in Gebrauch. In einem Abschluss-Handler ist das meist ein erneut zugestellter Webhook. |
| 409 | ERROR_KEY_NAME_AMBIGUOUS | Das Löschen per Name traf auf mehrere Treffer. Löschen Sie stattdessen über den Wert. |
| 404 | ERROR_KEY_NOT_FOUND | Das Löschen traf auf nichts. Meist eine bereits verarbeitete Kündigung. |
| 500 | ERROR_ADMIN_STORE_FAILURE | Speichern nicht möglich. Meist Dateimodus ohne ausgewählte Datei. |
Diese Codes stehen neben den Fehlercodes fürs Lösen, sie ersetzen sie nicht, und der vollständige Satz steht in der CapSkip API-Dokumentation.
FAQ
Wie schnell wirkt ein neuer Schlüssel wirklich?
Ab der nächsten Anfrage zum Lösen. Nichts wird zwischengespeichert und nichts muss neu geladen werden, ein Kunde, der seinen Schlüssel auf Ihrer Kassenseite bekommt, kann ihn also in derselben Minute nutzen. Der Entzug wirkt in die andere Richtung genauso sofort, und deshalb ist der Zeitpunkt Ihres Kündigungs-Handlers eine Frage der Richtlinie und nicht der Technik.
Kostet mich jeder weitere Kundenschlüssel etwas?
Nein. CapSkip läuft auf Ihrer eigenen Hardware ohne Kontingent pro Lösung, ein Schlüssel ist also ein Etikett für einen Aufrufer und keine Abrechnungsidentität. Legen Sie einen pro Kunde an, oder mehrere pro Kunde, wenn Sie dessen Umgebungen trennen wollen, und löschen Sie sie genauso frei wieder. Das SDK zum Captcha-Lösen liest genau den Schlüssel, den Sie ihm übergeben, wie Sie die Aufteilung schneiden, entwerfen also ganz allein Sie.
Kann ich über diese API einen Kunden messen oder drosseln?
Über diese API nicht. Sie legt Schlüssel an, listet sie auf und löscht sie, und keine andere Einstellung ist darüber lesbar oder änderbar. Unterscheiden sich Ihre Tarife nach Volumen, zählen Sie die Anfragen an dem Reverse Proxy, den Sie ohnehin vor die Instanz setzen, anhand des API-Schlüssels, den der Kunde mitschickt. Der Schlüssel identifiziert den Aufrufer, und Ihr Proxy entscheidet, was dieser Aufrufer darf.
Ich habe den Admin-token verloren. Was jetzt?
Erzeugen Sie im selben Einstellungsbereich einen neuen. Der alte token verliert sofort seine Gültigkeit, es gibt also keinen Aufräumschritt und kein Zeitfenster, in dem beide gelten. Ihre Kunden merken davon nichts: Ihre Schlüssel bleiben unberührt und sie lösen weiter. Kaputt geht nur Ihre eigene Bereitstellung, bis Sie das Geheimnis aktualisiert haben, das Ihr Webhook-Handler liest.
Die kürzeste Fassung
Schalten Sie Remote Key Management einmal ein und bewahren Sie den token bei Ihren übrigen Billing-Geheimnissen auf. Legen Sie einen nach dem Kunden benannten Schlüssel an, sobald dessen Abonnement aktiv wird, behandeln Sie den 409 bei einer Wiederholung als Erfolg, und löschen Sie über denselben Namen, wenn das Abonnement endet. Listen Sie nach Zeitplan auf und gleichen Sie mit Ihren aktiven Abonnenten ab, denn nur dort steht die echte Antwort. Setzen Sie dann einen Proxy davor und halten Sie den Admin-Pfad von dem Port fern, den Ihre Kunden sehen. Tun Sie das, dann wird Captcha-Umgehung zu etwas, das Sie auf eigener Hardware weiterverkaufen können, bereitgestellt so schnell, wie Ihre Kasse einen Webhook auslösen kann.
