我试图验证一个web钩子签名,我有来自api2cart文档的这个PHP代码,但是我需要它在Javascript.I中,我尝试了,但是我无法匹配签名和HMAC生成的值,更详细的这里
应采取以下步骤:
使用您的store_key作为密钥生成二进制签名
$headersForJson = [
'X-Webhook-Error-Code' => '0',
'X-Webhook-Action' => 'update',
'X-Webhook-Timestamp' => '1516291592',
'X-Webhook-Entity' => 'product',
'X-Webhook-Store-Id' => '1',
'X-Webhook-Signature' => 'SGVsbG8gd2l0aCBBUEkyQ2FydA==',
];
$signatureFromRequest = $headersForJson['X-Webhook-Signature'];
unset($headersForJson['X-Webhook-Signature']);
ksort($headersForJson);
$headers = json_encode($headersForJson);
$data = $headers . $params['raw_body'];
$generatedSignature = base64_encode(hash_hmac('sha256', $data, $storeKey, true));
if (hash_equals($signatureFromRequest, $generatedSignature)) {
return true;
}以下是我所做的:
const signature = headers['x-webhook-signature'];
delete headers['x-webhook-signature'];
// the header contained other keys I had to get keys starting with x-webhooks
let xkeys = Object.keys(headers).filter(key => key.includes('x-webhook-')).sort();
let xheaders = JSON.stringify(xkeys.reduce((res, key) => Object.assign(res, { [key]: headers[key] }), {}));
let data = xheaders + rawBody
const generatedHash = createHmac('SHA256', "SecretKey")
.update(data, 'utf-8')
.digest('base64');
return generatedHash === signature我在这里错过了什么?
发布于 2021-10-28 07:28:30
您需要将头数组键从x-web钩子实体转换为X-web钩子实体。
例如:
let xheaders = JSON.stringify(
xkeys.reduce((res, key) => Object.assign(
res,
{ [key.split('-').map(s => s[0].toUpperCase() + s.slice(1)).join('-')]: headers[key] }),//format header key from x-webhook-entity to X-Webhook-Entity
{}
)
);使用Pipe梦的完整代码:
const crypto = require('crypto');
const storeKey = '5d780e682fbdbd4d04411be86ccd4b30';
const signature = event.headers['x-webhook-signature'];
const headers = event.headers;
delete headers['x-webhook-signature'];
// the header contained other keys I had to get keys starting with x-webhooks
let xkeys = Object.keys(headers).filter(key => key.includes('x-webhook-')).sort();
let xheaders = JSON.stringify(
xkeys.reduce((res, key) => Object.assign(
res,
{ [key.split('-').map(s => s[0].toUpperCase() + s.slice(1)).join('-')]: headers[key] }),//format header key from x-webhook-entity to X-Webhook-Entity
{}
)
);
const data = xheaders + JSON.stringify(event.body);
const generatedHash = crypto.createHmac('SHA256', storeKey)
.update(data, 'utf-8')
.digest('base64');
console.log(signature);
console.log(generatedHash);
let status = 403;
if (signature === generatedHash) {
status = 200;
}
const response = await $respond({
status: status,
immediate: true,
headers: {},
body: {"signature":signature, "generatedHash":generatedHash}
})
return JSON.parse(response.config.data).response发布于 2021-10-29 11:27:01
我也有同样的问题,我用:
这对我来说很管用:
const validateRequest = (headers, body, storeKey) => {
const webhookHeaders = {
"X-Webhook-Action": headers["x-webhook-action"],
"X-Webhook-Entity": headers["x-webhook-entity"],
"X-Webhook-Error-Code": headers["x-webhook-error-code"],
"X-Webhook-Store-Id": headers["x-webhook-store-id"],
"X-Webhook-Timestamp": headers["x-webhook-timestamp"]
};
const signatureFromRequest = headers["x-webhook-signature"];
const data = JSON.stringify(webhookHeaders) + JSON.stringify(body);
const generatedSignature = crypto
.createHmac("sha256", storeKey)
.update(data)
.digest("base64");
return !!crypto.timingSafeEqual(
Buffer.from(signatureFromRequest),
Buffer.from(generatedSignature)
);
};你可以这样称呼它:
const headers = {
"x-webhook-entity": "product",
"x-webhook-action": "update",
"x-webhook-store-id": "0",
"x-webhook-error-code": "0",
"x-webhook-timestamp": "1635502511",
"x-webhook-signature": "Ua1dtsDBi+37fEGr3mTHN7laZqLQpl+tEK02RDAg++0="
};
const body = { id: "28" };
const storeKey = "ed58a22dfecb405a50ea3ea56979360d";
const isValid = validateRequest(headers, body, storeKey);
console.log(isValid ? "success" : "failed"); // successhttps://stackoverflow.com/questions/67941788
复制相似问题