如何从 HTTP POST webhook 接收原始 JSON 响应?
我正在使用 API 并验证对 webhook 的 POST 确实来自相应的公司 API,他们建议使用此方法:
To allow a client to verify a webhook message has in fact come from SIGNIFYD, an X-SIGNIFYD-SEC-HMAC-SHA256 header is included in each webhook POST message. The contents of this header is the Base64 encoded output of the HMAC SHA256 encoding of the JSON body of the message, using the team's API key as the encryption key. To verify the authenticity of the webhook message, you should calculate this value yourself and verify it equals the value contained in the header.
对于测试环境,“ secret ” key 是 ABCDE
而不是“团队 API key ”。
我像这样用 PHP 接收它:
<?php
// Get relevant Signifyd custom headers to be used for verification
$header_sig_topic = $_SERVER['HTTP_X_SIGNIFYD_TOPIC'];
$header_sig_sec_hmac = $_SERVER['HTTP_X_SIGNIFYD_SEC_HMAC_SHA256'];
// Get POST body
$webhookContent = "";
$webhook = fopen('php://input' , 'r');
while (!feof($webhook)) {
$webhookContent .= fread($webhook, 4096);
}
fclose($webhook);
?>
然后我像这样将它处理成散列:
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
但是,我哪里出错了,因为我计算的散列是
OTc1YzExZDY2ZTE1MTVmYmJmNWNhNDRhNWMxZGIzZDk0NmM3OGE4NDU2N2JkYTJmZDJlYWI0ODRhNjlhNTdiYg==
虽然相同样本响应 header 的 header 始终带有
W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=
我以为我弄错了 JSOn 正文,所以我尝试了 json_encode 和 json_decode 的所有组合,但没有任何帮助,我的哈希值永远不匹配。
我也尝试过使用 $webhookContent = json_decode(file_get_contents('php://input'), true);
来存储 POST 正文,但结果是空的($_POST 没有' 工作)。
除了接收 JSON,我是否还做错了什么?
作为测试响应正文的 JSON 始终带有 W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=
作为用于验证的哈希键:
{ "analysisUrl": "https://signifyd.com/v2/cases/1/analysis", "entriesUrl": "https://signifyd.com/v2/cases/1/entries", "notesUrl": "https://signifyd.com/v2/cases/1/notes", "orderUrl": "https://signifyd.com/v2/cases/1/order", "guaranteeEligible":false, "status":"DISMISSED", "uuid":"709b9107-eda0-4cdd-bdac-a82f51a8a3f3", "headline":"John Smith", "reviewDisposition":null, "associatedTeam":{ "teamName":"anyTeam", "teamId":26, "getAutoDismiss":true, "getTeamDismissalDays":2 }, "orderId":"19418", "orderDate":"2013-06-17T06:20:47-0700", "orderAmount":365.99, "createdAt":"2013-11-05T14:23:26-0800", "updatedAt":"2013-11-05T14:23:26-0800", "adjustedScore":262.6666666666667, "investigationId":1, "score":262.6666666666667, "caseId":1, "guaranteeDisposition":"APPROVED"}
如果有助于了解我哪里出错了,提供了一个示例,但它是用 Python 编写的:
Mac sha256HMAC = javax.crypto.Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(teamAPIKEY.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String encodedHMAC256 = Base64.encodeBase64String(sha256HMAC.doFinal(jsonBody.getBytes("UTF-8")));
最佳答案
我的错误在于没有将 $raw_output
parameter of the hash_hmac()
function 指定为 true
。
raw_output
When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
因此,由于我没有将 $raw_output
指定为 true
,所以我得到的是 hexits
而不是原始二进制输出,看起来像这个:975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb
。
编辑:这里的答案是
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret, true);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
关于php - 将 PHP POST 响应的 JSON 主体编码为 HMAC SHA256,然后编码为 Base64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38092371/