ahmad-shawky / laravel-webhook-server
在 Laravel 应用中发送 webhook
Requires
- php: ^7.2
- ext-json: *
- guzzlehttp/guzzle: ^6.3
- illuminate/bus: ^6.0
- illuminate/queue: ^6.0
- illuminate/support: ^6.0
Requires (Dev)
- orchestra/testbench: ^3.8
- phpunit/phpunit: ^8.2
- spatie/test-time: ^1.0
README
这是一个从 spatie 包分支出来以支持 php7.2 的版本。要安装此版本,请使用 composer require ahmad-shawky/laravel-webhook-server
从 Laravel 应用发送 webhook
webhook 是一个应用程序向另一个应用程序提供特定事件信息的方式。两个应用程序之间通过简单的 HTTP 请求进行通信。
此包允许您轻松地在 Laravel 应用中配置和发送 webhook。它支持 签名调用、重试调用和回退策略。
如果您需要接收和处理 webhook,请查看我们的 laravel-webhook-client 包。
安装
您可以通过 composer 安装此包
composer require spatie/laravel-webhook-server
您可以使用以下命令发布配置文件:
php artisan vendor:publish --provider="Spatie\WebhookServer\WebhookServerServiceProvider"
这是将被发布到 config/webhook-server.php
的文件内容
return [ /* * The default queue that should be used to send webhook requests. */ 'queue' => 'default', /* * The default http verb to use. */ 'http_verb' => 'post', /* * This class is responsible for calculating the signature that will be added to * the headers of the webhook request. A webhook client can use the signature * to verify the request hasn't been tampered with. */ 'signer' => \Spatie\WebhookServer\Signer\DefaultSigner::class, /* * This is the name of the header where the signature will be added. */ 'signature_header_name' => 'Signature', /* * These are the headers that will be added to all webhook requests. */ 'headers' => [], /* * If a call to a webhook takes longer that this amount of seconds * the attempt will be considered failed. */ 'timeout_in_seconds' => 3, /* * The amount of times the webhook should be called before we give up. */ 'tries' => 3, /* * This class determines how many seconds there should be between attempts. */ 'backoff_strategy' => \Spatie\WebhookServer\BackoffStrategy\ExponentialBackoffStrategy::class, /* * By default we will verify that the ssl certificate of the destination * of the webhook is valid. */ 'verify_ssl' => true, ];
默认情况下,此包使用队列来重试失败的 webhook 请求。请确保在非本地环境中设置除 sync
之外的真实队列。
使用方法
这是调用 webhook 的最简单方法
WebhookCall::create() ->url('https://other-app.com/webhooks') ->payload(['key' => 'value']) ->useSecret('sign-using-this-secret') ->dispatch();
这将向 https://other-app.com/webhooks
发送 POST 请求。请求正文将是传递给 payload
的数组的 JSON 编码版本。请求将包含一个名为 Signature
的头,该头将包含接收应用程序可以使用的签名,以 验证 负载数据是否被篡改。
如果接收应用程序没有以以 2
开头的响应代码响应,则包将在 10 秒后重试调用 webhook。如果第二次尝试失败,则包将在 100 秒后尝试最终调用 webhook。如果该尝试失败,将引发 FinalWebhookCallFailedEvent
。
请求签名的工作方式
在设置时,通常会在您的应用程序和希望接收 webhook 的应用程序之间生成、存储和共享一个密钥。生成密钥可以使用 Illuminate\Support\Str::random()
完成,但这完全取决于您。该包将使用密钥来签名 webhook 调用。
默认情况下,该包将添加一个名为 Signature
的头,其中包含接收应用程序可以使用的签名,以验证负载数据是否被篡改。以下是计算该签名的方式:
// payload is the array passed to the `payload` method of the webhook // secret is the string given to the `signUsingSecret` method on the webhook. $payloadJson = json_encode($payload); $signature = hash_hmac('sha256', $payloadJson, $secret);
自定义签名请求
如果您想自定义签名过程,可以创建自己的自定义签名者。签名者可以是任何实现 Spatie\WebhookServer\Signer
的类。
该接口看起来如下:
namespace Spatie\WebhookServer\Signer; interface Signer { public function signatureHeaderName(): string; public function calculateSignature(array $payload, string $secret): string; }
创建您的签名者后,您可以在 webhook-server
配置文件的 signer
键中指定它的类名。然后,您的签名者将在所有 webhook 调用中默认使用。
您也可以为特定的 webhook 调用指定一个签名者
WebhookCall::create() ->signUsing(YourCustomSigner::class) ... ->dispatch();
如果您想自定义头部的名称,不需要使用自定义签名者,但可以更改 webhook-server
配置文件中的 signature_header_name
的值。
重试失败的 webhook
当我们发送webhook的应用程序无法以2xx
状态码发送响应时,该包将认为调用失败。如果远程应用程序在3秒内没有响应,也将认为调用失败。
您可以在webhook-server
配置文件的timeout_in_seconds
键中配置默认超时时间。或者,您可以通过以下方式覆盖特定webhook的超时时间:
WebhookCall::create() ->timeoutInSeconds(5) ... ->dispatch();
当webhook调用失败时,我们将再次尝试调用两次。您可以在配置文件的tries
键中设置默认的重试次数。或者,您可以指定特定webhook的重试次数,如下所示:
WebhookCall::create() ->maximumTries(5) ... ->dispatch();
为了不频繁调用远程应用程序,我们将在每次尝试之间等待一段时间。默认情况下,我们在第一次和第二次尝试之间等待10秒,在第三次和第四次之间等待100秒,在第四次和第五次之间等待1000秒,依此类推。我们将等待的最大秒数是100000,大约是27小时。此行为在默认的ExponentialBackoffStrategy
中实现。
您可以通过创建一个实现Spatie\WebhookServer\BackoffStrategy\BackoffStrategy
的类来自定义回退策略。这个接口看起来是这样的:
namespace Spatie\WebhookServer\BackoffStrategy; interface BackoffStrategy { public function waitInSecondsAfterAttempt(int $attempt): int; }
您可以通过在webhook-server
配置文件的backoff_strategy
中指定其完全限定类名来将自定义策略指定为默认策略。或者,您可以指定特定webhook的策略,如下所示。
WebhookCall::create() ->useBackoffStrategy(YourBackoffStrategy::class) ... ->dispatch();
在底层,webhook调用的重试是通过延迟分派实现的。Amazon SQS只支持较小的最大延迟。如果您使用Amazon SQS作为您的队列,请确保您没有配置该包,以免在每次尝试之间有超过15分钟的时间。
自定义HTTP动词
默认情况下,所有webhook都将使用post
方法。您可以通过在webhook-server
配置文件的http_verb
键中指定所需的HTTP动词来自定义此操作。
您也可以通过使用useHttpVerb
方法来覆盖特定调用。
WebhookCall::create() ->useHttpVerb('get') ... ->dispatch();
添加额外的头信息
您可以通过将它们添加到webhook-server
配置文件的headers
键中来使用额外的头信息。如果您想为特定webhook添加额外的头信息,可以使用withHeaders
调用。
WebhookCall::create() ->withHeaders([ 'Another Header' => 'Value of Another Header' ]) ... ->dispatch();
验证接收应用程序的SSL证书
当使用以https://
开头的URL时,该包将验证接收方的SSL证书是否有效。如果它无效,我们将认为webhook调用失败。我们不推荐这样做,但您可以通过将webhook-server
配置文件中的verify_ssl
键设置为false
来关闭此验证。
您还可以使用doNotVerifySsl
方法来禁用特定webhook调用的验证。
WebhookCall::create() ->doNotVerifySsl() ... ->dispatch();
添加元信息
您可以为webhook添加额外的元信息。这些元信息将不会传输,并且仅供传递给此包引发的事件使用。
这是添加元信息的方法:
WebhookCall::create() ->meta($arrayWithMetaInformation) ... ->dispatch();
添加标签
如果您使用Laravel Horizon作为您的队列,您会很高兴知道我们支持标签。
要为执行webhook调用的底层作业添加标签,只需在webhook-server
配置文件的tags
键中指定它们或使用withTags
方法。
WebhookCall::create() ->withTags($tags) ... ->dispatch();
事件
该包触发以下事件
WebhookCallSucceededEvent
:远程应用程序以2xx
响应代码响应。WebhookCallFailedEvent
:远程应用返回了非2xx
响应码,或者根本未响应FinalWebhookCallFailedEvent
:调用 webhook 的最后尝试失败。
所有这些事件都具有以下属性
httpVerb
:执行请求所用的动词webhookUrl
:请求发送到的 URLpayload
:使用的有效负载headers
:发送的头部。此数组包括签名头部meta
:使用 meta 调用 传递给 webhook 的值数组tags
:使用的 标签 数组attempt
:尝试次数response
:远程应用返回的响应。可以是\GuzzleHttp\Psr7\Response
的实例或null
。
测试
composer test
变更日志
请参阅 变更日志 了解最近发生的更改。
贡献
请参阅 贡献指南 了解详细信息。
安全性
如果您发现任何安全相关的问题,请通过电子邮件 freek@spatie.be 而不是使用问题跟踪器来报告。
明信片软件
您可以自由使用此包,但如果它进入了您的生产环境,我们非常感谢您从家乡寄给我们一张明信片,提及您正在使用哪个/哪些我们的包。
我们的地址是:Spatie,Samberstraat 69D,2060 安特卫普,比利时。
我们将所有收到的明信片 发布在我们的公司网站上。
鸣谢
支持我们
Spatie 是一家位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到我们所有开源项目的概述 在这里。
您的业务依赖于我们的贡献吗?联系并支持我们在 Patreon。所有承诺都将致力于分配人力进行维护和开发新的酷炫功能。
许可证
MIT 许可证(MIT)。请参阅 许可证文件 了解更多信息。