Linux中國

本地開發如何測試 Webhook

Webhook 可用於外部系統通知你的系統發生了某個事件或更新。可能最知名的 Webhook 類型是支付服務提供商(PSP)通知你的系統支付狀態有了更新。

它們通常以監聽的預定義 URL 的形式出現,例如 http://example.com/webhooks/payment-update。同時,另一個系統向該 URL 發送具有特定有效載荷的 POST 請求(例如支付 ID)。一旦請求進入,你就會獲得支付 ID,可以通過 PSP 的 API 用這個支付 ID 向它們詢問最新狀態,然後更新你的資料庫。

其他例子可以在這個對 Webhook 的出色的解釋中找到:https://sendgrid.com/blog/whats-webhook/

只要系統可通過互聯網公開訪問(這可能是你的生產環境或可公開訪問的臨時環境),測試這些 webhook 就相當順利。而當你在筆記本電腦上或虛擬機內部(例如,Vagrant 虛擬機)進行本地開發時,它就變得困難了。在這些情況下,發送 webhook 的一方無法公開訪問你的本地 URL。此外,監視發送的請求也很困難,這可能使開發和調試變得困難。

因此,這個例子將解決:

  • 測試來自本地開發環境的 webhook,該環境無法通過互聯網訪問。從伺服器向 webhook 發送數據的服務無法訪問它。
  • 監控發送的請求和數據,以及應用程序生成的響應。這樣可以更輕鬆地進行調試,從而縮短開發周期。

前置需求:

  • 可選:如果你使用虛擬機(VM)進行開發,請確保它正在運行,並確保在 VM 中完成後續步驟。
  • 對於本教程,我們假設你定義了一個 vhost:webhook.example.vagrant。我在本教程中使用了 Vagrant VM,但你可以自由選擇 vhost。
  • 按照這個安裝說明安裝 ngrok。在 VM 中,我發現它的 Node 版本也很有用:https://www.npmjs.com/package/ngrok,但你可以隨意使用其他方法。

我假設你沒有在你的環境中運行 SSL,但如果你使用了,請將在下面的示例中的埠 80 替換為埠 433,http:// 替換為 https://

使 webhook 可測試

我們假設以下示例代碼。我將使用 PHP,但請將其視作偽代碼,因為我留下了一些關鍵部分(例如 API 密鑰、輸入驗證等)沒有編寫。

第一個文件:payment.php。此文件創建一個 $payment 對象,將其註冊到 PSP。然後它獲取客戶需要訪問的 URL,以便支付並將用戶重定向到客戶那裡。

請注意,此示例中的 webhook.example.vagrant 是我們為開發設置定義的本地虛擬主機。它無法從外部世界進入。

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    &apos;order_id&apos; => 123,
    &apos;amount&apos; => 25.00,
    &apos;description&apos; => &apos;Test payment&apos;,
    &apos;redirect_url&apos; => &apos;http://webhook.example.vagrant/redirect.php&apos;,
    &apos;webhook_url&apos; => &apos;http://webhook.example.vagrant/webhook.php&apos;,
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

第二個文件:webhook.php。此文件等待 PSP 調用以獲得有關更新的通知。

<?php
/*
 * This file gets called by the PSP and in the $_POST they submit an &apos;id&apos;
 * We can use this ID to get the latest status from the PSP and update our internal systems afterward
 */

$paymentId = $_POST[&apos;id&apos;];
$paymentInfo = $paymentProvider->getPayment($paymentId);
$status = $paymentInfo->getStatus();

// Perform actions in here to update your system
if ($status === &apos;paid&apos;) {
    ..
}
elseif ($status === &apos;cancelled&apos;) {
    ..
}

我們的 webhook URL 無法通過互聯網訪問(請記住它:webhook.example.vagrant)。因此,PSP 永遠不可能調用文件 webhook.php,你的系統將永遠不會知道付款狀態,這最終導致訂單永遠不會被運送給客戶。

幸運的是,ngrok 可以解決這個問題。 ngrok 將自己描述為:

ngrok 通過安全隧道將 NAT 和防火牆後面的本地伺服器暴露給公共互聯網。

讓我們為我們的項目啟動一個基本的隧道。在你的環境中(在你的系統上或在 VM 上)運行以下命令:

ngrok http -host-header=rewrite webhook.example.vagrant:80

閱讀其文檔可以了解更多配置選項:https://ngrok.com/docs

會出現這樣的屏幕:

ngrok 輸出

我們剛剛做了什麼?基本上,我們指示 ngrok 在埠 80 建立了一個到 http://webhook.example.vagrant 的隧道。同一個 URL 也可以通過 http://39741ffc.ngrok.iohttps://39741ffc.ngrok.io 訪問,它們能被任何知道此 URL 的人通過互聯網公開訪問。

請注意,你可以同時獲得 HTTP 和 HTTPS 兩個服務。這個文檔提供了如何將此限制為 HTTPS 的示例:https://ngrok.com/docs#bind-tls

那麼,我們如何讓我們的 webhook 現在工作起來?將 payment.php 更新為以下代碼:

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    &apos;order_id&apos; => 123,
    &apos;amount&apos; => 25.00,
    &apos;description&apos; => &apos;Test payment&apos;,
    &apos;redirect_url&apos; => &apos;http://webhook.example.vagrant/redirect.php&apos;,
    &apos;webhook_url&apos; => &apos;https://39741ffc.ngrok.io/webhook.php&apos;,
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

現在,我們告訴 PSP 通過 HTTPS 調用此隧道 URL。只要 PSP 通過隧道調用 webhook,ngrok 將確保使用未修改的有效負載調用內部 URL。

如何監控對 webhook 的調用?

你在上面看到的屏幕截圖概述了對隧道主機的調用,這些數據相當有限。幸運的是,ngrok 提供了一個非常好的儀錶板,允許你檢查所有調用:

我不會深入研究這個問題,因為它是不言自明的,你只要運行它就行了。因此,我將解釋如何在 Vagrant 虛擬機上訪問它,因為它不是開箱即用的。

儀錶板將允許你查看所有調用、其狀態代碼、標頭和發送的數據。你將看到應用程序生成的響應。

儀錶板的另一個優點是它允許你重放某個調用。假設你的 webhook 代碼遇到了致命的錯誤,開始新的付款並等待 webhook 被調用將會很繁瑣。重放上一個調用可以使你的開發過程更快。

默認情況下,儀錶板可在 http://localhost:4040 訪問。

虛擬機中的儀錶盤

為了在 VM 中完成此工作,你必須執行一些額外的步驟:

首先,確保可以在埠 4040 上訪問 VM。然後,在 VM 內創建一個文件已存放此配置:

web_addr: 0.0.0.0:4040

現在,殺死仍在運行的 ngrok 進程,並使用稍微調整過的命令啟動它:

ngrok http -config=/path/to/config/ngrok.conf -host-header=rewrite webhook.example.vagrant:80

儘管 ID 已經更改,但你將看到類似於上一屏幕截圖的屏幕。之前的網址不再有效,但你有了一個新網址。 此外,Web Interface URL 已更改:

現在將瀏覽器指向 http://webhook.example.vagrant:4040 以訪問儀錶板。另外,對 https://e65642b5.ngrok.io/webhook.php 做個調用。這可能會導致你的瀏覽器出錯,但儀錶板應顯示正有一個請求。

最後的備註

上面的例子是偽代碼。原因是每個外部系統都以不同的方式使用 webhook。我試圖基於一個虛構的 PSP 實現給出一個例子,因為可能很多開發人員在某個時刻肯定會處理付款。

請注意,你的 webhook 網址也可能被意圖不好的其他人使用。確保驗證發送給它的任何輸入。

更好的的,可以向 URL 添加令牌,該令牌對於每個支付是唯一的。只有你的系統和發送 webhook 的系統才能知道此令牌。

祝你測試和調試你的 webhook 順利!

注意:我沒有在 Docker 上測試過本教程。但是,這個 Docker 容器看起來是一個很好的起點,並包含了明確的說明:https://github.com/wernight/docker-ngrok

via: https://medium.freecodecamp.org/testing-webhooks-while-using-vagrant-for-development-98b5f3bedb1d

作者:Stefan Doorn 譯者:wxy 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國