在本地开发时如何测试Webhooks

2020年12月30日10:54:52 发表评论 112 次浏览

斯蒂芬·多恩(Stefan Doorn)

在本地开发时如何测试Webhooks1

摄影者

费尔南多·万扎诺

on

不飞溅

网络挂钩可以由外部系统用来通知系统有关某个事件或更新的信息。可能最知名的类型是付款服务提供商(PSP)通知你的系统有关付款状态更新的类型。

通常, 它们以你在预定义URL上侦听的形式出现。例如http://example.com/webhooks/payment-update。同时, 另一个系统将带有一定负载的POST请求发送到该URL(例如, 付款ID)。收到请求后, 你将获取付款ID, 通过其API向PSP询问最新状态, 然后再更新数据库。

在有关Webhooks的出色说明中可以找到其他示例。https://sendgrid.com/blog/whats-webhook/.

只要可以通过Internet公开访问该系统, 这些Web钩子的测试就相当顺利。这可能是你的生产环境或可公开访问的登台环境。当你在笔记本电脑上或在虚拟机(例如, VM, Vagrant box)内进行本地开发时, 这将变得更加困难。在这种情况下, 发送Webhook的一方无法公开访问本地URL。另外, 监视发送的请求很困难, 这可能会使开发和调试变得困难。

此示例将解决什么:

  • 从本地开发环境测试Webhook, 该环境无法通过Internet访问。从服务器将数据发送到Webhook的服务无法访问它。
  • 监视发送的请求和数据, 以及应用程序生成的响应。这将使调试更加容易, 从而缩短开发周期。

先决条件:

  • 可选的:如果你正在使用虚拟机(VM)进行开发, 请确保其正在运行, 并确保在VM中完成了后续步骤。
  • 对于本教程, 我们假设你在以下位置定义了一个虚拟主机:webhook.example.vagrant。我在本教程中使用了Vagrant VM, 但是你可以自由选择虚拟主机的名称。
  • 安装恩格罗克通过遵循安装说明。在VM内, 我发现它的Node版本也很有用:https://www.npmjs.com/package/ngrok, 但随时可以使用其他方法。

我假设你的环境中没有运行SSL, 但是如果这样做, 请随时将端口80替换为端口433, http://与https://在以下示例中。

使Webhook可测试

让我们假设以下示例代码。我将使用PHP, 但是当我遗漏了一些关键部分(例如API密钥, 输入验证等)时, 将其读为伪代码。

第一个文件:Payment.php。该文件创建付款对象, 然后将其注册到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 = [
    'order_id' => 123, 'amount' => 25.00, 'description' => 'Test payment', 'redirect_url' => 'http://webhook.example.vagrant/redirect.php', 'webhook_url' => 'http://webhook.example.vagrant/webhook.php', ];

$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 'id'
 * We can use this ID to get the latest status from the PSP and update our internal systems afterward
 */
 
$paymentId = $_POST['id'];
$paymentInfo = $paymentProvider->getPayment($paymentId);
$status = $paymentInfo->getStatus();

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

我们的webhook URL无法通过Internet访问(请记住:webhook.example.vagrant)。因此, 文件webhook.phpPSP永远不会调用它。你的系统永远不会了解付款状态。最终导致订单永远不会交付给客户。

幸运的是恩格罗克可以解决这个问题。恩格罗克描述为:

ngrok通过安全隧道将位于NAT和防火墙之后的本地服务器公开到公共Internet。

让我们为我们的项目开始一个基本的隧道。在你的环境(系统或VM上)上, 运行以下命令:

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

在他们的文档中了解更多配置选项:https://ngrok.com/docs.

这样的屏幕将会出现:

在本地开发时如何测试Webhooks2

ngrok输出

我们刚刚开始了什么?基本上, 我们指示恩格罗克开始通往http://webhook.example.vagrant在端口80上。现在可以通过以下方式访问相同的URLhttp://39741ffc.ngrok.ioorhttps://39741ffc.ngrok.io, 任何知道此URL的人都可以通过Internet公开访问它们。

注意你可以立即使用HTTP和HTTPS。该文档提供了有关如何仅将其限制为HTTPS的示例:https://ngrok.com/docs#bind-tls.

那么, 我们如何使我们的网络挂钩现在工作?更新资料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 = [
    'order_id' => 123, 'amount' => 25.00, 'description' => 'Test payment', 'redirect_url' => 'http://webhook.example.vagrant/redirect.php', 'webhook_url' => 'https://39741ffc.ngrok.io/webhook.php', ];

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

现在, 我们告诉PSP通过HTTPS调用隧道URL。恩格罗克一旦PSP通过隧道调用了Webhook, 将确保使用未经修改的有效负载调用你的内部URL。

如何监控对网络挂钩的呼叫?

你在上面看到的屏幕快照概述了对隧道主机进行的呼叫。该数据是相当有限的。幸好, 恩格罗克提供了一个非常好的仪表板, 可让你检查所有呼叫:

在本地开发时如何测试Webhooks3

我不会深入探讨这个问题, 因为一旦运行它就可以不言自明。因此, 我将在"无业游民"框中解释如何访问它, 因为它无法立即使用。

仪表板将允许你查看所有呼叫, 其状态代码, 标题和正在发送的数据。你还将看到应用程序生成的响应。

仪表板的另一个简洁功能是允许你重播特定呼叫。假设你的Webhook代码遇到致命错误, 开始新的付款并等待该Webhook被调用很繁琐。重播上一个调用可以使你的开发过程更快。

默认情况下, 可以通过以下方式访问仪表板http:// localhost:4040。

VM中的仪表板

为了使此功能在VM中起作用, 你必须执行一些其他步骤:

首先, 确保可以在端口4040上访问VM。然后, 在包含此配置的VM内部创建一个文件:

web_addr:0.0.0.0:4040

现在, 杀死恩格罗克仍在运行的进程, 并使用此经过稍微调整的命令启动它:

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

尽管ID已更改, 但你会看到一个类似于上一个屏幕截图的屏幕。以前的网址不再可用, 但是你获得了新的网址。另外, 网页界面网址已更改:

在本地开发时如何测试Webhooks4

现在将浏览器定向到http://webhook.example.vagrant:4040访问仪表板。另外, 拨打https://e65642b5.ngrok.io/webhook.php.这可能会导致浏览器出错, 但是仪表板应显示正在发出的请求。

结束语

上面的示例是伪代码。原因是每个外部系统都以不同的方式使用webhooks。我试图给出一个基于虚拟PSP实现的示例, 因为可能很多开发人员有时需要处理付款。

请注意, 你的Webhook URL也可能被恶意使用。确保验证发送给它的所有输入。

最好还向URL添加一个令牌, 该令牌对于每次付款都是唯一的。只有系统和发送Webhook的系统才能知道此令牌。

祝你好运, 测试和调试你的Webhooks!

注意:我尚未在Docker上测试过本教程。但是, 此Docker容器看起来是一个很好的起点, 并且包含明确的说明。https://github.com/wernight/docker-ngrok.

斯蒂芬·多恩

https://github.com/stefandoorn

https://www.linkedin.com/in/stefandoorn

一盏木

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: