我正在尝试集成来自Todoist的Webhooks API。我获得了正确的头和正文信息,但无法验证X Hmac- the 256报头。来自Todoist文档:
为了验证每个web钩子请求确实是由Todoist发送的,包含了一个X Hmac- the 256报头;它是一个使用您的SHA256 client_secret作为加密密钥生成的,而整个请求有效负载是要加密的消息。生成的Hmac将被编码为base64字符串。
下面是我使用express.js的web钩子路由的代码和用于解密的Node.js密码库:
app.post("/webhooks/todoist", async (req, res) => {
// this is my stored client secret from Todoist
const secret = keys.todoistClientSecret
// Using the Node.js Crypto library
const hash = crypto.createHmac('sha256', secret)
.update(req.toString()) // <-- is this the "whole request payload"?
.digest("base64");
// These 2 are not equal
console.log("X-Todoist-Hmac-SHA256:", req.header("X-Todoist-Hmac-SHA256"))
console.log("Hash:", hash)
res.status(200).send()
})
我已经发现req是IncomingMessage类型的。Crypto库只接受某些类型,如果传递req对象本身,则得到以下错误:
"data“参数必须是string类型或缓冲区、TypedArray或DataView的实例。
将“整个请求有效负载”传递给密码库的正确方法是什么?
发布于 2020-06-01 14:13:31
好的,在尝试错误处理其他变体之后,我找到了解决方案。您必须将JSON.stringify(req.body)作为要加密的消息传递。也许这对其他人有帮助。
const hash = crypto.createHmac('sha256', secret)
.update(JSON.stringify(req.body)) // <-- this is the needed message to encrypt
.digest("base64");
特殊字符编码的导入更新
我在我的快速设置中使用了app.use(bodyParser.json())。这将不适用于具有特殊特征的请求机构(如德文Umlauts,ü)。相反,我必须像这样设置主体解析器:
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf
}
}))然后,在加密中,它必须是JSON.stringify(req.body),而不是传递req.rawBody。所以密码库的最终代码如下所示:
const secret = keys.todoistClientSecret
const hash = crypto.createHmac('sha256', secret)
.update(req.rawBody)
.digest("base64");
https://stackoverflow.com/questions/62133039
复制相似问题