验证webhook的真实性
简介
webhook提供了额外的安全措施,以验证webhook是真实的,来自Zendesk。亚博如果你想确保只有Zendesk webhook被制作到你的端点,并确保信息是真实的,并且符合系统的预期,亚博这是很有用的。这些签名还将有助于防止重放攻击。验证签名秘密是可选的。
Webhook请求将包含两个头部,可用于验证请求的真实性:
X-亚博Zendesk-Webhook-Signature
-主签名X-亚博Zendesk-Webhook-Signature-Timestamp
—用于验证签名的时间戳
这与请求的有效负载(如果有的话)一起使用。
验证签名
使用SHA256的webhook密钥对body和签名时间戳进行签名,然后使用base64编码结果摘要。
代表:base64(HMACSHA256(TIMESTAMP + BODY))
要验证签名,请创建相同的SHA256 HMAC签名,然后将其与webhook有效负载进行比较,以确保它们匹配。如果它们匹配,那么你可以确定网络钩子来自Zendesk。亚博如果他们没有,这可能是来自其他来源的请求。
并非所有来自webhook的请求都有一个主体(get, delete),所以确保在任何验证码中都考虑到这种情况。根据语言的不同,这可能是一个空字符串或null。有关详细信息,请参阅您的语言文档。
NodeJS验证示例
下面的例子展示了如何使用NodeJS和Express验证签名。在生产环境中,该检查应该构成接受或拒绝webhook请求的检查的一部分。
常量表达=需要(“表达”);
常量加密=需要(“密码”);
需要(“body-parser-xml”)(表达);
// webhook本身的签名秘密
常量SIGNING_SECRET=“dGhpc19zZWNyZXRfaXNfZm9yX3Rlc3Rpbmdfb25seQ = = ";
//总是sha256
常量SIGNING_SECRET_ALGORITHM=“sha256”;
常量港口=3000;
常量应用程序=表达();
函数isValidSignature(签名,身体,时间戳){
让hmac=加密.createHmac(SIGNING_SECRET_ALGORITHM,SIGNING_SECRET);
让团体=hmac.更新(时间戳+身体).消化(“base64”);
返回(
缓冲.比较(
缓冲.从(签名),
缓冲.从(团体.toString(“base64”))
)= = =0
);
}
函数storeRawBody(要求的事情,res,缓冲区){
如果(缓冲区& &缓冲区.长度){
要求的事情.rawBody=缓冲区.toString(“utf8 ");
}
}
//根据请求格式使用中间件存储原始请求体
应用程序.使用(
表达.json({
验证:storeRawBody,
})
);
应用程序.使用(表达.urlencoded({验证:storeRawBody,扩展:真正的}));
应用程序.使用(表达.xml({验证:storeRawBody}));
应用程序.帖子(“/钩”,(要求的事情,res)= >{
//来自webhook请求的字段,每次都会改变
常量签名=要求的事情.头[“x-亚博zendesk-webhook-signature”];
常量时间戳=要求的事情.头[“x-亚博zendesk-webhook-signature-timestamp”];
常量身体=要求的事情.rawBody;
控制台.日志(
isValidSignature(签名,身体,时间戳)
?“HMAC签名有效”
:“HMAC签名无效”
);
res.状态(200).发送(“成功”);
});
应用程序.听(港口,()= >控制台.日志(`服务器在端口上运行$ {港口}`));
获取webhook的签名密钥
在UI中
在管理中心导航到webhook。在webhook详细信息页面上,密钥默认是隐藏的。可以通过点击“揭示秘密”来揭示。
在API中
使用显示webhook签名秘密API去找回秘密。
注意:秘密密钥应该像任何其他凭证一样对待,不应该提交到代码中或公开暴露。
重置密钥
重置密钥将生成一个新的密钥,从那时起将用于新的webhook请求。您应该确保在更改后在服务器上更新新密钥,因为新的请求可能无法通过验证。
在新webhook上签署秘密
在创建webhook之前,您可能需要测试它。签名秘密只有在webhook完全创建后才会生成。这意味着要在创建过程中测试webhook,你需要使用静态签名秘密。
在创建一个测试webhook之前,验证它的静态秘密总是:dGhpc19zZWNyZXRfaXNfZm9yX3Rlc3Rpbmdfb25seQ = =
请注意:您仍然需要使用此秘密验证签名以验证您的测试。
一旦创建了webhook,就会为它生成一个单独的签名秘密。正在更新和测试的现有webhook将为webhook使用适当的签名秘密,而不是静态秘密。
在应用程序需求中定义webhook的签名密钥
对于需要webhook的应用程序,应用程序开发者可以在他们的应用程序要求中定义一个16-64字符的字母数字密钥。该密钥将用于他们的应用程序创建的网络钩子,用于签名验证。
与其他方式创建的webhook的密钥不同,Zendesk管理员不能查看或重置在应用程序要求中定义的密钥。亚博