我正在使用gocardless钩子,并且我被困在沙箱环境中验证hmac签名。
因此,我在沙箱中生成了webhook测试,并在发送时将请求正文和头部提供给我。
因此,据我所知,我必须获取请求正文并生成一个带有密钥的散列,并将其与webhook签名头部散列进行比较(听起来并不是很复杂)。
因此,我使用postman在我的本地环境中复制它,附加相同的标题和相同的正文,但签名永远不匹配。
这是我尝试过的:
$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中对其进行编码……但没有成功。
那么,这里会有什么问题呢?也许签名在沙箱环境中不起作用?有没有人用过它?
提前感谢!
发布于 2016-07-31 21:12:05
最后我发现了问题所在,在沙箱面板的goocardless中,他们显示了请求未最小化的,所以长度是不同的,只要缩小它,你就可以测试了!现在签名匹配了!
发布于 2016-09-16 22:42:53
我们已经更新了开发人员文档,您可以在https://developer.gocardless.com/getting-started/api/staying-up-to-date-with-webhooks/?lang=php#building-a-webhook-handler上找到验证webhook签名的示例
你想做一些像这样的事情
<?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");
}https://stackoverflow.com/questions/38684174
复制相似问题