Deutsch

Entwicklertools · UUID Generator

Idempotenzschlüssel: Verwenden eines vom Client generierten UUID, um Wiederholungsversuche sicher zu machen

· Warum es wichtig ist

UUID Kryptographie Browser-APIs

Ein Sequenzdiagramm, das zeigt, wie ein Client denselben Idempotenzschlüssel zweimal sendet und der Server die zwischengespeicherte Antwort zurückgibt
Original-ToolAcre-Vektorillustration

Eine Zeitüberschreitung bei einer Zahlungsanforderung lässt Sie unsicher sein, ob sie erfolgreich durchgeführt wurde. Mit Idempotenzschlüsseln können Sie es sicher erneut versuchen, und ein von CSPRNG generierter UUID ist der natürliche Schlüssel. In diesem Beitrag wird das Muster ausführlich erklärt.

Die Zeitüberschreitung, die dem Kunden möglicherweise das Doppelte in Rechnung gestellt hätte – die Fehlermodus-Idempotenzschlüssel müssen behoben werden

Ein Timeout während einer Zahlungsanforderung führt zu echter Unsicherheit für den Kunden und das System. Ihr HTTP-Client hat das Warten auf eine Antwort aufgegeben, aber der Zahlungsserver hat die Transaktion möglicherweise verarbeitet, bevor die Verbindung geschlossen wurde oder eine Zeitüberschreitung aufgetreten ist. Wenn Sie dieselbe Anfrage erneut versuchen, berechnen Sie dem Kunden möglicherweise das Doppelte. Wenn Sie es nicht erneut versuchen, wird die Zahlung nie abgeschlossen. Das Zahlungssystem scheitert an einem unglücklichen Mittelweg: Das Geld des Kunden ist möglicherweise weg, kommt morgen an, bleibt in einer Verarbeitungswarteschlange hängen oder hat das Konto überhaupt nicht verlassen. Diese Unklarheit ist für Finanzsysteme inakzeptabel.

Funktionsweise von Idempotenzschlüsseln: Der Server speichert die erste Antwort unter dem Schlüssel und spielt sie bei Wiederholungen ab

Idempotenzschlüssel lösen dieses Problem auf elegante Weise, indem sie Wiederholungsversuche sicher und deterministisch machen. Der Kunde generiert für jede Absicht – eine Zahlung, eine Überweisung, eine Gebühr – einen eindeutigen Schlüssel und fügt ihn in jede Anfrage ein. Der Server verarbeitet die Zahlung, speichert die Antwort unter diesem Schlüssel zwischen und speichert sowohl den Schlüssel als auch das Ergebnis. Wenn derselbe Schlüssel innerhalb eines Aufbewahrungsfensters erneut eintrifft, gibt der Server die zwischengespeicherte Antwort erneut ab, ohne die Zahlung erneut zu verarbeiten. Der Kunde kann es mit der Gewissheit erneut versuchen, dass der exakt gleiche Schlüssel immer zum gleichen Ergebnis führt, egal wie oft er gesendet wird. Dieses Muster beseitigt die Mehrdeutigkeit und macht die Wiederholungslogik sicher.

Vor dem ersten Versuch generieren – warum der Schlüssel vorhanden sein muss, bevor die Anforderung verlassen wird, und beim erneuten Versuch wörtlich wiederverwendet werden muss

Das Muster ist älter als moderne HTTP-Spezifikationen, hat jedoch nach weit verbreiteten finanziellen Verlusten und Kundenbeschwerden aufgrund doppelter Gebühren im Zahlungsverkehr an Bedeutung gewonnen. Jede Zahlungs-API und viele Webdienst-APIs unterstützen jetzt Idempotenzschlüssel. Ein von CSPRNG generierter UUID ist die natürliche Wahl für den Schlüssel, da er nicht zu erraten ist, ohne jegliche Koordination zwischen Clients eindeutig ist und keine serverseitige Zuweisung oder zentrale Autorität erfordert. Der Client generiert es vor dem ersten Versuch, verwendet es wörtlich bei jedem erneuten Versuch und erhält jedes Mal die gleiche Antwort. Für die Koordinierung der Schlüsselgenerierung ist kein serverseitiger Status erforderlich.

Warum ein zufälliger UUID und kein Zähler- oder Nutzlast-Hash – Einzigartigkeit ohne Koordination und keine versehentliche Wiederverwendung über Absichten hinweg

Der Schlüssel muss vorhanden sein, bevor die Anforderung den Client verlässt, da die Generierung bei einem erneuten Versuch zu spät ist, um Idempotenz sicherzustellen. Wenn die erste Anfrage erfolgreich war und dem Kunden eine Gebühr in Rechnung gestellt wurde, würde die Generierung eines neuen Schlüssels bei einem erneuten Versuch das Problem verschleiern und erneut in Rechnung stellen. Der Client muss sich vor dem ersten Versuch auf einen Schlüssel festlegen, ihn im Speicher oder im persistenten Speicher speichern und denselben Schlüssel wiederverwenden, wenn eine Zeitüberschreitung oder ein erneuter Versuch erforderlich wird. Für manuelle API-Tests erzeugt der ToolAcre-Generator Schlüssel, die Sie in Curl oder einen REST-Client einfügen, kopieren und über mehrere Anfragen hinweg wiederverwenden können, um das Idempotenzverhalten zu testen.

Umfang und Lebensdauer – Schlüssel pro Vorgang, pro Konto und wie lange der Server sie speichern soll

Warum ein UUID anstelle eines Hash- oder sequentiellen Zählers für Idempotenzschlüssel? Ein Hash der Anforderungsnutzlast scheint intuitiv zu sein – identische Nutzlasten erhalten identische Hashes und damit identische Schlüssel. Aber Hashes sind für diesen Anwendungsfall schwach, weil zwei nahezu identische Anfragen mit unterschiedlichen Beträgen, unterschiedlichen Empfängern oder unterschiedlichen Parametern völlig unterschiedliche Hashes erzeugen und somit separate Gebühren generieren, was zwar korrekt ist, aber nicht den gesamten erforderlichen Schutz bietet. Ein sequentieller Zähler erfordert Koordination und einen verteilten Zustand: Wenn zwei Clients beide zählerbasierte Schlüssel in Ihrer Infrastruktur generieren, kann es zu einer Kollision ihrer Zähler kommen. Ein UUID erfordert keine zentrale Autorität, ist nicht zu erraten und es ist äußerst unwahrscheinlich, dass er zu jeder Zeit im gesamten Internet zufällig kollidiert.

Funktioniertes Beispiel – eine Wiederholungssequenz mit demselben Schlüssel, die jedes Mal zeigt, was der Client sendet und was der Server zurückgibt

Die serverseitige Implementierung speichert Antworten unter Schlüsseln und gibt bei Wiederholungen zwischengespeicherte Antworten zurück. Die Komplexität liegt in der Entscheidung über praktische betriebliche Fragen: die Aufbewahrungsfrist, wie lange ein Schlüssel gespeichert werden muss, die Cache-Größe, wie viele Schlüssel gespeichert werden müssen, Sperren, wie verhindert werden kann, dass zwei gleichzeitige Anfragen mit demselben Schlüssel die Zahlung zweimal verarbeiten, und Bereinigung, wann ein Schlüssel vergessen werden sollte. Hierbei handelt es sich um Speicher- und Zuverlässigkeitsfragen, die außerhalb des Anwendungsbereichs des UUID-Generators liegen. Die Aufgabe des Clients besteht darin, einen guten Schlüssel zu generieren und ihn bei Wiederholungsversuchen wiederzuverwenden. Die Aufgabe des Servers besteht darin, den Cache korrekt und dauerhaft zu implementieren.

Was dies nicht abdeckt – die serverseitige Speicherung und Sperrung, die zur Implementierung des Musters erforderlich ist, was ein separates Design darstellt

Ein ausgearbeitetes Beispiel zeigt einen typischen Ablauf in der Praxis. Eine mobile App muss mithilfe einer API, die Idempotenz unterstützt, Geld an einen Freund überweisen. Vor dem Senden der Anfrage generiert die App mithilfe ihrer lokalen Kryptobibliothek einen UUID oder ruft zu Testzwecken einen vom ToolAcre-Generator ab: 3fa85f64-5717-4562-b3fc-2c963f66afa6. Die App sendet eine POST-Anfrage an /transfers mit einem JSON-Body und einem HTTP-Header-Idempotency-Key: 3fa85f64-5717-4562-b3fc-2c963f66afa6. Der Server verarbeitet die Übertragung, speichert 3fa85f64-5717-4562-b3fc-2c963f66afa6 → {status: „success“, transferId: „xfer-12345“} in seinem Cache und gibt eine 200-Antwort mit dem Ergebnis zurück.

Takeaway: eine Absicht, ein Schlüssel – der ToolAcre-Generator stellt Ihnen ein CSPRNG-gestütztes UUID zur Verfügung, das Sie als Schlüssel beim manuellen Testen einer Integration verwenden können

Das Netzwerk läuft ab und der Client sieht die Antwort vom ersten Versuch nicht. Die App wiederholt dieselbe Anfrage mit demselben Idempotenzschlüssel, ohne ein neues UUID zu generieren. Der Server erkennt den Schlüssel in seinem Cache, findet die zwischengespeicherte Antwort und gibt sofort {status: „success“, transferId: „xfer-12345“} zurück, ohne eine neue Übertragung zu verarbeiten und ohne den Kunden erneut zu belasten. Die Operation ist idempotent: Ein erneuter Versuch führt jedes Mal zum gleichen beobachtbaren Ergebnis. Für einen funktionierenden Test kann der ToolAcre-Generator den Schlüssel bereitstellen; Generieren Sie ein UUID, fügen Sie es in den Header ein, beobachten Sie die Antwort und senden Sie es erneut mit demselben Schlüssel, um zu überprüfen, ob der Server das Caching korrekt implementiert.