React und PHP
Dieses Beispiel schützt das Kontaktformular einer bestehenden Anwendung. Das Frontend ist eine React-Anwendung mit Vite, das Backend ein PHP-Server. Beide laufen bereits. Für das Myra EU CAPTCHA ändern Sie nur die unten mit einem Pfeil markierten Dateien.
Voraussetzungen
Die folgenden Voraussetzungen sind erfüllt:
| Voraussetzung | Wert |
|---|---|
| Node.js mit npm | installiert |
| PHP | ab Version 8.0 |
| Composer | installiert |
| Sitekey | Öffentlicher Sitekey und Secret aus der Ansicht Details |
Achtung
Der öffentliche Sitekey gehört ins Frontend, das Secret ausschließlich ins Backend. Ein Secret im Auslieferungspaket des Frontends liest jeder Besucher mit.
Projektstruktur
Die folgenden Dateien ändern sich. Alles Übrige im Projekt bleibt unverändert:
mein-projekt/
├── frontend/ # bestehende React-Anwendung (Vite)
│ ├── package.json # ← Schritt 1: Paket @myrasec/eu-captcha eintragen
│ ├── vite.config.ts
│ ├── index.html
│ └── src/
│ ├── main.tsx
│ ├── App.tsx
│ └── ContactForm.tsx # ← Schritt 1 und 2: Widget einbinden, Token absenden
└── backend/ # bestehender PHP-Server
├── composer.json # ← Schritt 3: Paket myra-security-gmbh/eu-captcha eintragen
├── vendor/
├── .env # ← Sitekey und Secret eintragen
└── public/
└── index.php # ← Schritt 3: Prüfung an den Anfang des Handlers setzen
Schritt 1: Widget einbinden
Das Formular steht in der Datei frontend/src/ContactForm.tsx.
Installieren Sie das Paket:
Setzen Sie die Komponente EuCaptcha in das Formular und nehmen Sie das Token über den Callback onComplete entgegen:
import { useState } from "react";
import { EuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha";
const captchaSitekey = "EUCAPTCHA_SITE_KEY";
export function ContactForm() {
const [token, setToken] = useState("");
// handleSubmit folgt in Schritt 2
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<textarea name="message" required />
{/* onComplete liefert das Token, sobald die Challenge abgeschlossen ist */}
<EuCaptcha sitekey={captchaSitekey} onComplete={setToken} />
<button type="submit">Submit</button>
</form>
);
}
Die Komponente lädt das Skript verify.js, legt den iframe des Widgets an und startet die Challenge selbsttätig.
Schritt 2: Token absenden
Prüfen Sie vor dem Absenden mit isEuCaptchaDone(), ob die Challenge abgeschlossen ist. Senden Sie das Token anschließend im Feld eu-captcha-response des JSON-Rumpfs:
async function handleSubmit(e: React.FormEvent<HTMLFormElement>): Promise<void> {
e.preventDefault();
if (!isEuCaptchaDone()) {
// challenge not yet complete
return;
}
const fields = Object.fromEntries(new FormData(e.currentTarget));
const res = await fetch("/api/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...fields, "eu-captcha-response": token }),
});
if (res.ok) {
// success
}
}
Hinweis
Die Komponente EuCaptcha legt das Widget nur neu an, wenn sich sitekey, theme, width, height, widgetId oder autostart ändern. Ein erneutes Zeichnen des Formulars, etwa bei jeder Eingabe, lässt das Widget unberührt. Das gilt auch für eigene Inline-Funktionen für onComplete, onExpired oder onError.
Schritt 3: Token prüfen
Die Prüfung gehört in den serverseitigen Handler, der die Formulardaten entgegennimmt, hier /api/submit in der Datei backend/public/index.php. Sie steht an erster Stelle, vor jeder Verarbeitung.
Installieren Sie das Paket mit der Versionsangabe ^2.0.1:
Lesen Sie die Felder aus dem JSON-Rumpf und setzen Sie die Prüfung an den Anfang des Handlers:
<?php
require __DIR__ . '/vendor/autoload.php';
use Myrasec\EuCaptcha;
// Felder aus dem JSON-Rumpf lesen
$body = json_decode(file_get_contents('php://input'), true) ?: [];
// Prüfung vor jeder Verarbeitung
$captcha = new EuCaptcha(
sitekey: getenv('EUCAPTCHA_SITE_KEY'),
secret: getenv('EUCAPTCHA_SECRET_KEY'),
);
if (!$captcha->validate()->success()) {
http_response_code(400);
exit('captcha verification failed');
}
// ab hier die bisherige Logik
$email = $body['email'];
$message = $body['message'];
mail('team@example.com', 'Kontakt', $message);
echo 'Danke!';
Hinweis
Der Aufruf validate() liest das Token selbsttätig aus dem Feld eu-captcha-response, sowohl aus einem Formularfeld als auch aus einem JSON-Rumpf. Die IP-Adresse des Besuchers liest der Aufruf aus den Kopfzeilen. Halten Sie Sitekey und Secret in der Datei .env, aus der getenv sie liest.
Siehe PHP.
Integration prüfen
Ansicht Integration Test mit dem Ergebnis Fully Integrated
Prüfen Sie zum Schluss in der Ansicht Integration Test des Sitekeys, ob Frontend und Backend zusammenspielen. Danach trägt der Sitekey den Status Fully Integrated.
Siehe Integration testen.
