開發者工具 · UUID 產生器
冪等金鑰:使用客戶端產生的 UUID 確保重試安全
· 為什麼它很重要
uuid 密碼學 瀏覽器 API
付款請求逾時會讓您不確定是否已完成。冪等金鑰可讓您安全地重試,CSPRNG 產生的 UUID 是自然金鑰。這篇文章端到端地解釋了這個模式。
可能向客戶收取兩次費用的逾時 - 存在故障模式冪等鍵來修復
付款請求期間的逾時會為客戶端和系統帶來真正的不確定性。您的 HTTP 用戶端放棄等待回應,但支付伺服器可能在連線關閉或逾時之前處理了交易。如果您重試相同要求,您可能會向客戶收取兩次費用。如果您不重試,付款將永遠無法完成。支付系統陷入了一個不幸的中間地带:客戶的钱可能消失了,可能明天到達,可能被困在處理隊列中,或者可能根本没有离開帳戶。這種模糊性對於金融體系來說是不可接受的。
冪等鍵的工作原理—伺服器將第一個回應儲存在該鍵下並重播它以進行重複
冪等鍵藉由使重試安全且具有確定性,優雅地解決了這個問題。客戶端為每個意圖(付款、轉帳、收費)產生一個唯一的金鑰,並將其包含在每個請求中。伺服器處理支付,快取該密鑰下的回應並儲存密鑰和結果。如果相同的金鑰在保留視窗內再次到達,伺服器將重播快取的回應,而不再次處理付款。客戶可以放心地重試,因為他們知道完全相同的金鑰始終會產生相同的結果,無論發送多少次。這種模式消除了歧義並使重試邏輯安全。
在第一次嘗試之前產生 - 為什麼金鑰必須在請求離開之前存在並在重試時逐字重複使用
該模式比現代 HTTP 規範更古老,但在廣泛的財務損失和客戶因重複收費而投訴後,在支付領域獲得了突出地位。每個支付 API 和許多 Web 服務 API 現在都支持幂等性密钥。 CSPRNG 產生的 UUID 是金鑰的自然選擇,因為它是不可猜測的、唯一的,無需客戶端之間的任何協調,並不需要伺服器端分配或中央權限。客戶端在第一次嘗試之前產生它,在每次重試時逐字重複使用它,每次都會收到相同的回應。不需要伺服器端狀態來協調金鑰產生。
為什麼是隨機的 UUID 而不是計數器或有效負載雜湊 - 沒有協調的唯一性,並不會在意圖之間意外重複使用
該金鑰必須在請求離開客戶端之前存在,因為在重試時產生金鑰為時已晚,無法確保冪等性。如果第一個請求成功並向客戶收費,則重試時產生新金鑰將掩蓋問題並再次收費。客戶端必須在第一次嘗試之前提交金鑰,將其儲存在記憶體或持久性儲存中,並在需要逾時或重試時重複使用相同金鑰。對於手動 API 測試,ToolAcre 產生器會產生金鑰,您可以將其貼上到curl 或 REST 用戶端中,在多個請求之間複製和重複使用以測試冪等性行為。
範圍和生命週期 - 每個操作、每個帳戶的金鑰以及伺服器應記住它們的時間
為什麼冪等鍵使用 UUID 而不是雜湊或順序計數器?請求有效負載的雜湊值看起來很直觀——相同的有效負載會獲得相同的雜湊值,從而獲得相同的金鑰。但哈希對於這種用例來說很弱,因為兩個幾乎相同的請求具有不同的金額、不同的接收者或不同的參數,會產生完全不同的哈希,從而產生單獨的費用,這是正確的,但不能提供所需的所有保護。順序計數器需要協調和分散式狀態:如果兩個用戶端都在您的基礎架構上產生基於計數器的金鑰,則它們的計數器可能會發生衝突。 UUID 不需要中央權威,是不可猜測的,並極不可能在整個互聯網上隨時發生偶然衝突。
工作範例 - 使用相同金鑰的重試序列,顯示客戶端發送的內容和伺服器每次傳回的內容
伺服器端實作將回應儲存在鍵下,並在重複時傳回快取的回應。複雜性在於決定實際操作問題:記住一個金鑰的保留期限多長時間,快取大小要記住多少個金鑰,鎖定如何防止具有相同金鑰的兩個並發請求處理兩次支付以及何時忘記金鑰進行清理。這些是 UUID 產生器範圍之外的儲存和可靠性問題。客戶端的工作是產生一個好的金鑰並在重試時重複使用它;伺服器的工作是正確且持久地實現快取。
這不包括實現該模式所需的伺服器端儲存和鎖定,這是一個單獨的設計
一個工作範例顯示了實踐中的典型序列。行動應用程式需要使用支援冪等性的 API 向朋友轉帳。在傳送請求之前,應用程式使用其本機加密庫產生一個 UUID 或從 ToolAcre 產生器中取得一個用於測試目的:3fa85f64-5717-4562-b3fc-2c963f66afa6。應用程式向 /transfers 發送 POST 請求,其中包含 JSON 主體和 HTTP 標頭冪等密鑰:3fa85f64-5717-4562-b3fc-2c963f66afa6。伺服器處理傳輸,將 3fa85f64-5717-4562-b3fc-2c963f66afa6 → {status: "success", transferId: "xfer-12345"} 儲存在其快取中,並傳回 200 回應和結果。
重點:一心一鍵——ToolAcre 產生器為您提供了一個由 CSPRNG 支援的 UUID,可在手動測試整合時用作密鑰
網路超時,客戶端看不到第一次嘗試的回應。應用程式使用相同的冪等性金鑰重試相同的請求,而不產生新的 UUID。伺服器識別其快取中的金鑰,找到快取的回應並立即返回 {status: "success", transferId: "xfer-12345"} ,無需處理新的傳輸,也無需再次向客戶收費。此操作是冪等的:每次重試都會產生相同的可觀察結果。對於有效的測試, ToolAcre 產生器可以提供金鑰;產生 UUID,將其包含在標頭中,觀察回應並使用相同的金鑰重新傳送以驗證伺服器正確實現快取。