obhut Gate in Formulare integrieren
Kontrolliert freigeschaltete Bot-Prüfung einbetten, Tokens im eigenen Backend verifizieren und Fehler geschlossen behandeln.
obhut Gate prüft Formulare, Registrierungen und andere missbrauchsanfällige
Aktionen, bevor dein Backend sie ausführt. Der sitekey gehört in die öffentliche
Webseite. Das Secret ist dagegen ein Server-Zugangsschlüssel und darf weder im HTML
noch im Browser-JavaScript oder in öffentlichen Logs stehen.
Integriere Gate erst, wenn das Dashboard für deine Umgebung einen konkreten HTTPS-Gate-Endpunkt anzeigt. Fehlt diese Adresse, ist Gate dort noch nicht freigeschaltet. Verwende keinen geratenen oder aus Beispielen übernommenen Hostnamen.
Widget vorbereiten
Widget und Hostnamen anlegen
Lege im Dashboard ein Gate-Widget an und trage jeden erlaubten Hostnamen
exakt ein, zum Beispiel app.example.de. Verwende keine Platzhalterdomain
und beschränke Produktions- und Test-Hostnamen auf die tatsächlich
benötigten Einträge.
Secret einmalig sichern
Der öffentliche sitekey bleibt für die Einbettung sichtbar. Das Secret
wird bei Erstellung oder Rotation nur einmal angezeigt. Lege es sofort im
Secret Store deines Backends ab. Eine Rotation ersetzt das bisherige Secret.
HTTPS-Endpunkt übernehmen
Kopiere die im Dashboard angezeigte HTTPS-Adresse. Browser und Backend verwenden dieselbe Basisadresse; der Browser erhält trotzdem niemals das Secret.
Widget einbetten
Ersetze GATE-BASIS-URL durch den vollständigen Ursprung aus dem Dashboard,
einschließlich https://, und SITEKEY durch den dort angezeigten öffentlichen
Schlüssel:
<form method="post" action="/konto-anlegen">
<!-- eigene, serverseitig validierte Formularfelder -->
<div class="obhut-gate" data-sitekey="SITEKEY"></div>
<button type="submit">Konto anlegen</button>
</form>
<script
src="GATE-BASIS-URL/__obhut/gate/widget.js"
defer
></script>Nach einer erfolgreichen Prüfung schreibt das Widget den Token in ein
verstecktes Feld namens obhut-gate-response. Ein normales HTML-Formular sendet
dieses Feld an dein Backend. Für eine JavaScript-Anwendung kannst du zusätzlich
einen Callback registrieren:
<div
class="obhut-gate"
data-sitekey="SITEKEY"
data-callback="onGateSolved"
></div>
<script>
function onGateSolved(token) {
// Token zusammen mit der geschützten Aktion an das eigene Backend senden.
}
</script>Der Callback und das versteckte Feld sind nur Transportwege. Sie sind kein Sicherheitsentscheid, weil Browserdaten verändert werden können.
Führe die geschützte Aktion nur aus, wenn dein Backend siteverify aufgerufen
und in einer gültigen JSON-Antwort exakt success: true erhalten hat. Ein
fehlender Token, ein Netzwerkfehler, ungültiges JSON und jede andere Antwort
müssen die Aktion ablehnen.
Token im Backend verifizieren
Sende den Token als JSON an
POST /__obhut/gate/siteverify des freigeschalteten Gate-Endpunkts:
curl --fail-with-body 'GATE-BASIS-URL/__obhut/gate/siteverify' \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"secret": "SECRET-AUS-DEM-SECRET-STORE",
"response": "TOKEN-AUS-OBHUT-GATE-RESPONSE"
}'In Node.js ist keine zusätzliche Bibliothek erforderlich:
export async function gateErlaubt({ gateUrl, secret, response, remoteip }) {
try {
const requestBody = { secret, response };
if (remoteip) requestBody.remoteip = remoteip;
const result = await fetch(
new URL("/__obhut/gate/siteverify", gateUrl),
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
signal: AbortSignal.timeout(5_000),
},
);
if (!result.ok) return false;
const body = await result.json();
return body.success === true;
} catch {
return false;
}
}AbortSignal.timeout(5_000) begrenzt den externen Aufruf hier auf fünf Sekunden.
Passe die Frist an dein eigenes Ende-zu-Ende-Zeitbudget an, entferne sie aber nicht
ersatzlos.
Der HTTP-Status allein ist kein Erfolgssignal: Fachliche Ablehnungen werden
meist mit HTTP 200 und success: false beantwortet. Bei Erfolg enthält die
Antwort zusätzlich challenge_ts und hostname.
Status und Fehlercodes
| HTTP | Ergebnis | Behandlung |
|---|---|---|
200 | success: true | Die geprüfte Aktion darf fortgesetzt werden. |
200 | success: false, missing-input-secret oder invalid-input-secret | Serverkonfiguration prüfen; Aktion ablehnen. |
200 | success: false, missing-input-response oder invalid-input-response | Neuen Browser-Token anfordern; Aktion ablehnen. |
200 | success: false, timeout-or-duplicate | Token ist abgelaufen oder bereits verbraucht; Widget neu laden und erneut prüfen. |
200 | success: false, bad-request | JSON und Feldnamen korrigieren; Aktion ablehnen. |
429 | success: false, quota-exceeded | Keine geschützte Aktion ausführen; Freigabegrenze im Dashboard prüfen. |
| anderer Status, Timeout oder ungültiges JSON | kein verlässlicher Entscheid | Aktion ablehnen und einen kontrollierten neuen Versuch anbieten. |
Auch das Browser-Widget kann eine Prüfung ablehnen, etwa bei einem unbekannten
sitekey, einem nicht freigegebenen Hostnamen oder einer abgelaufenen Challenge.
Dann bleibt obhut-gate-response leer und das Widget setzt seinen Zustand auf
error. Das Backend muss den fehlenden Token unabhängig von der Browseranzeige
ablehnen.
Gültigkeit und Wiederholungen
Ein erfolgreicher Token ist fünf Minuten gültig und kann genau einmal per
siteverify verbraucht werden. Sende denselben Token nicht erneut. Bei
timeout-or-duplicate oder einem mehrdeutigen Netzwerkfehler:
- geschützte Aktion nicht ausführen;
- Formular beziehungsweise Widget neu laden und einen neuen Token erzeugen;
- die vollständige Anfrage mit dem neuen Token wiederholen;
- die eigene fachliche Aktion zusätzlich idempotent auslegen, falls ihr Client-Wiederholungen nicht ausschließen könnt.
Optionale IP-Bindung
Das Feld remoteip ist optional. Übermittle es nur, wenn dein Backend die
tatsächliche Besucher-IP über eine vollständig kontrollierte und vertrauenswürdige
Proxy-Kette bestimmt. Kopiere keine vom Browser frei gesetzten
X-Forwarded-For- oder ähnlichen Header. Eine übermittelte IP muss der beim
Lösen beobachteten IP entsprechen; andernfalls ist die Antwort
invalid-input-response. Wenn du keinen vertrauenswürdigen Client-IP-Pfad hast,
lasse remoteip weg.
Content Security Policy und Browser
Für eine bestehende Content Security Policy muss der konkrete Gate-Ursprung an zwei Stellen freigegeben sein:
script-srcbeziehungsweisescript-src-elemfürwidget.js;connect-srcfür die JSON-Aufrufe anchallengeundverify.
Das Widget benötigt JavaScript, fetch, TextEncoder und WebCrypto
(crypto.subtle) in einem sicheren HTTPS-Kontext. Fehlt eine dieser Funktionen
oder blockiert die CSP einen Aufruf, entsteht kein gültiger Token. Behandle das
wie jeden anderen geschlossenen Fehlerpfad. Prüfe die Einbettung in den von dir
unterstützten Browsern und in deiner tatsächlichen CSP vor dem Rollout.
Datenschutz
Gate setzt für die Prüfung keine Tracking-Cookies und verwendet keine
credentialed Browser-Anfragen. Cookieless bedeutet jedoch nicht, dass keine
Daten verarbeitet werden: Das Widget übermittelt begrenzte Browser- und
Gerätesignale; beim HTTPS-Aufruf fallen außerdem übliche Verbindungs- und
Anfragesignale wie IP-Adresse und User-Agent an. Sie dienen der Risikoprüfung.
Der Solve-Token ist an den sitekey gebunden. Bei einer Hostnamen-Allowlist muss
der beim Lösen gespeicherte Hostname weiterhin erlaubt sein; ein übermitteltes
remoteip bindet zusätzlich die Besucher-IP. Der User-Agent wird bei siteverify
nicht erneut verglichen. Die Produktstatistik verwendet aggregierte Zähler statt
einzelner Besucherprofile. Prüfe unabhängig davon deine eigene
Datenschutzerklärung, Rechtsgrundlage, Backend-Logs und Aufbewahrung.
Wechsel von einem anderen Anbieter
Gate verwendet einen vertrauten Ablauf aus öffentlichem Website-Schlüssel, Browser-Token und serverseitiger Prüfung, ist aber kein Drop-in-Austausch. Übernimm keine bestehenden Schlüssel oder Secrets. Passe Script-URL, Feldnamen, JSON-Anfrage, Fehlerbehandlung und CSP bewusst an und teste den gesamten Ablauf in einer freigeschalteten Umgebung, bevor du den bisherigen Anbieter entfernst.