为什么 Stripe 的 webhook 不需要验证签名?
Why Stripe's webhooks do not need verify signature?
doc(https://stripe.com/docs/webhooks)和SDK(stripe-php)均未使用任何签名方法。所以我怀疑,如果有人假冒官方 webhook 发件人怎么办?
在SDK中,只有成功获取事件id才算是一个好的webhook,我觉得这太冒险了,不是吗?
您可以通过保存事件 ID 然后从条带中检索事件以确保事件有效来解决此问题:
\Stripe\Event::retrieve($event_id)
Stripe 确实提供了 web hooks 的签名。看这里:https://stripe.com/docs/webhooks#signatures
你也可以看看这篇文章:https://www.truespotmedia.com/testing-webhooks-in-stripe-with-php/
下面是一些示例代码:
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("your secret api key");
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = "whsec_...";
$payload = @file_get_contents("php://input");
$sig_header = $_SERVER["HTTP_STRIPE_SIGNATURE"];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
有两种方法可以做到这一点。它们已经涵盖了,但我会将所有内容合并为一个答案。
选项 1
检查事件是否有效(否则抛出异常)。
\Stripe\Event::retrieve($event_id)
选项 2
HMAC Stripe-Signature
header 使用仪表板中的 whsec*
键。
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = "whsec_...";
$payload = @file_get_contents("php://input");
$sig_header = $_SERVER["HTTP_STRIPE_SIGNATURE"];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
代码来自 https://stripe.com/docs/webhooks/signatures
选项 1 更简单,需要额外调用 API,但选项 2 要求您在应用程序中存储额外的密钥并需要代码(我更喜欢选项 1)。我今天咨询了 Stripe 支持人员,他们确认他们在验证 API 调用的有效性方面彼此一样好,所以这是一个选择问题。
doc(https://stripe.com/docs/webhooks)和SDK(stripe-php)均未使用任何签名方法。所以我怀疑,如果有人假冒官方 webhook 发件人怎么办?
在SDK中,只有成功获取事件id才算是一个好的webhook,我觉得这太冒险了,不是吗?
您可以通过保存事件 ID 然后从条带中检索事件以确保事件有效来解决此问题:
\Stripe\Event::retrieve($event_id)
Stripe 确实提供了 web hooks 的签名。看这里:https://stripe.com/docs/webhooks#signatures
你也可以看看这篇文章:https://www.truespotmedia.com/testing-webhooks-in-stripe-with-php/
下面是一些示例代码:
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("your secret api key");
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = "whsec_...";
$payload = @file_get_contents("php://input");
$sig_header = $_SERVER["HTTP_STRIPE_SIGNATURE"];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
有两种方法可以做到这一点。它们已经涵盖了,但我会将所有内容合并为一个答案。
选项 1
检查事件是否有效(否则抛出异常)。
\Stripe\Event::retrieve($event_id)
选项 2
HMAC Stripe-Signature
header 使用仪表板中的 whsec*
键。
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = "whsec_...";
$payload = @file_get_contents("php://input");
$sig_header = $_SERVER["HTTP_STRIPE_SIGNATURE"];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
代码来自 https://stripe.com/docs/webhooks/signatures
选项 1 更简单,需要额外调用 API,但选项 2 要求您在应用程序中存储额外的密钥并需要代码(我更喜欢选项 1)。我今天咨询了 Stripe 支持人员,他们确认他们在验证 API 调用的有效性方面彼此一样好,所以这是一个选择问题。