无gocardless PHP hmac签名不匹配


gocardless PHP hmac signature not match

我使用的是无gocardless挂钩,我一直在用沙箱环境验证hmac签名。

所以我在沙箱中生成了webhook测试,它会在发送请求时向我提供请求体和头。

因此,据我所知,我必须获得请求主体并生成一个带有密钥的哈希,并将其与webhook签名头哈希进行比较(听起来并不复杂)。

所以我使用poster在本地环境中复制它,附加相同的头和相同的正文,但签名永远不匹配。

以下是我尝试过的:

 $signature = hash_hmac('sha256',$request->getContent(), 'secret');

注意,我使用的是laravel框架,所以我的第一个想法可能是该框架在内部操纵请求,所以我尝试了这个:

 $request_data = file_get_contents('php://input');
 $signature = hash_hmac('sha256',$request_data, 'secret');

但仍然不匹配,我注意到了一些卑鄙的新行,也许这会修改结果,所以我清理了它。。。

 $request_data = str_replace(array('.', ' ', "'n", "'t", "'r"), '', $request_data);

但仍然不匹配,我还尝试在utf8中转换主体数据,并使hmac返回原始数据并在base64中编码。。。但没有成功。

那么这里可能出了什么问题呢?也许签名在沙箱环境中不起作用?有人处理过吗?

提前感谢!

最后我发现了这个问题,在goocardless中的沙盒面板中,他们显示了请求未经优化,所以长度不同,只需缩小它,您就可以进行测试了!现在签名匹配!

我们已经更新了开发人员文档,您可以在https://developer.gocardless.com/getting-started/api/staying-up-to-date-with-webhooks/?lang=php#building-a-webhook-handler

你想做一些类似的事情

<?php
// We recommend storing your webhook endpoint secret in an environment variable
// for security, but you could include it as a string directly in your code
$token = getenv("GC_WEBHOOK_SECRET");
$raw_payload = file_get_contents('php://input');
$headers = getallheaders();
$provided_signature = $headers["Webhook-Signature"];
$calculated_signature = hash_hmac("sha256", $raw_payload, $token);
if ($provided_signature == $calculated_signature) {
  // Process the events
  header("HTTP/1.1 200 OK");
} else {
  header("HTTP/1.1 498 Invalid Token");
}