Signaturprüfungsfehler von Webhooks beheben
Erfahren Sie, wie Sie einen häufigen Fehler beim Abhören von Webhook-Ereignissen beheben.
Bei der Verarbeitung von Webhook-Ereignissen empfehlen wir, Ihren Endpoint zu sichern, indem Sie überprüfen, ob das Ereignis von Stripe stammt. Verwenden Sie dazu den Header Stripe-Signature und rufen Sie die Funktion constructEvent() mit drei Parametern auf:
- requestBody: Der von Stripe gesendete Anfragetext für die Hauptzeichenfolge.
- signature: Der Stripe-Signature-Header in der von Stripe gesendeten Anfrage.
- endpointSecret: Der mit Ihrem Endpoint verknüpfte Geheimschlüssel.
Diese Funktion könnte wie folgt aussehen:
Sollten Sie die folgende Fehlermeldung erhalten: Webhook-Signaturüberprüfung fehlgeschlagen, ist mindestens einer der drei Parameter, die Sie an die Funktion constructEvent() übergeben haben, nicht korrekt.
Webhook signature verification failed. Err: No signatures found matching the expected signature for payload.
Endpoint-Geheimschlüssel prüfen
Der häufigste Fehler ist die Verwendung des falschen Endpoint-Geheimnisses. Wenn Sie einen im Dashboard erstellten Webhook-Endpoint verwenden, öffnen Sie den Endpoint im Dashboard und klicken Sie auf den Link Geheimnis anzeigen oben auf der Seite, um das Geheimnis anzuzeigen. Wenn Sie die Stripe-CLI verwenden, wird das Geheimnis im Terminal angezeigt, wenn Sie den Befehl stripe listen ausführen.
In beiden Fällen beginnt das Geheimnis mit einem whsec_ Präfix, aber das Geheimnis selbst ist anders. Überprüfen Sie Signaturen auf von der CLI weitergeleiteten Ereignisses nicht mit dem Geheimnis eines Dashboard-verwalteten Endpoints oder umgekehrt. Drucken Sie abschließend das endpointSecret in Ihrem Code aus und stellen Sie sicher, dass es mit dem oben gefundenen Geheimnis übereinstimmt.
Anfragetext prüfen
Der Anfragetext muss die Haupttext-Zeichenfolge sein, die Stripe in UTF-8-Codierung ohne Änderungen sendet. Wenn Sie dies als Zeichenfolge aufschreiben, sollte es in etwa so aussehen:
{ "id": "evt_xxx", "object": "event", "data": { ... } }
Den reinen Anfragetext abrufen
Einige Frameworks können den Anfragetext bearbeiten, indem sie zum Beispiel Leerzeichen hinzufügen oder entfernen, die Schlüsselwertpaare neu anordnen, die Zeichenfolge in das JSON-Format konvertieren oder die Codierung ändern. Alle diese Fälle führen zu einer fehlgeschlagenen Signaturprüfung.
Im Folgenden finden Sie eine nicht vollständige Liste der Frameworks, die die Daten mithilfe gängiger Konfigurationen analysieren oder ändern können, sowie einige Tipps zum Abrufen des Raw-Anfragetextes.
| Framework | Abrufmethode | 
|---|---|
| Stripe-Node-Bibliothek mit Express | Folgen Sie unserem Quickstart-Leitfaden für Integrationen. | 
| Stripe-Node-Bibliothek mit Body Parser | Probieren Sie die in diesem GitHub-Problem aufgeführten Lösungen. | 
| Stripe-Node-Bibliothek mit Next.js App-Router | Sehen Sie sich dieses funktionierende Beispiel an. | 
| Stripe-Node-Bibliothek mit Next.js Pages-Router | Versuchen Sie, bodyParserzu deaktivieren undbuffer(request)zu verwenden, wie in diesem Beispiel gezeigt. | 
Wenn Sie die Stripe-Node-Bibliothek mit Express verwenden, stellen Sie bitte sicher, dass app. nach der Webhook-Route platziert ist. In Express ist die Reihenfolge der Middleware-Konfiguration von Bedeutung. Wenn express. vor Ihrer Webhook-Route angewendet wird, analysiert es den Request-Body vor der Signaturüberprüfung, was dazu führt, dass die Überprüfung fehlschlägt. Beispiel:
// Webhook route in its original request form app.post('/webhook', ...); // Parse the request body in JSON for other routes app.use(express.json()); // Put other routes here app.post('/another-route', ...);
AWS API Gateway mit Lambda-Funktion
Um den Rohdaten-Anfragetext für das AWS API Gateway mit Lambda-Funktion abzurufen, richten Sie im API Gateway eine Textvorlage des Inhaltstyps application/json ein:
{ "method": "$context.httpMethod", "body": $input.json('$'), "rawBody": "$util.escapeJavaScript($input.body).replaceAll("\\'", "'")", "headers": { #foreach($param in $input.params().header.keySet()) "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end #end } }
Greifen Sie dann in der Lambda-Funktion auf den Raw-Body mit der rawBody-Eigenschaft des Ereignisses und die Header mit der headers-Eigenschaft des Ereignisses zu.
Signatur prüfen
Geben Sie den signature-Parameter ein und bestätigen Sie, dass er in etwa so aussieht:
t=xxx,v1=yyy,v0=zzz
Wenn nicht, prüfen Sie, ob ein Problem in Ihrem Code vorliegt, wenn versucht wird, die Signatur aus dem Header zu extrahieren.