java - Webhook 中的哈希验证
问题描述
我正在努力建立与名为Printify的服务的集成。我正在设置 webhook,最后一步我面临困难:哈希码的安全性。API 文档:https ://developers.printify.com/#webhooks --->保护您的 Webhooks。
流程如下:
- 通过 http api 创建一个 webhook 并传递一个额外的标头x-pfy-signature,其中包含一个密钥和一个我的系统将监听的可调用 url。
- 当调用 webhook 事件时,将调用该可调用 url。
- 我应该使用该密钥验证请求正文,以确保它是来自Printify的合法调用。
第 3 步是我遇到问题的地方。他们给出了 Python 中的示例代码:
import os
import hmac
def sha256hash(request):
hash = hmac.new(os.environ['SECRET_TOKEN'].encode('utf-8'),
request.data.encode('utf-8'),
'sha256')
return 'sha256=' + hash.hexdigest()
def secure_compare(a, b):
return hmac.compare_digest(a, b)
print('%r' % secure_compare(request.headers['x-pfy-signature'],
sha256hash(request)))
看来我正在通过输入从Printify收到的请求正文以及密钥来创建一些编码字符串,然后验证编码字符串是否与请求标头x-pfy-signature 匹配,这与初始的相同我通过了?
有人可以验证这是正确的并概述如何使用 Node 执行此操作吗?
解决方案
这是一个 NodeJS 解决方案:https ://bytethisstore.com/articles/pg/printify-webhooks-node-js
该文档实际上缺少一个步骤。创建密钥时,必须在创建 webhook 时将其作为名为“secret”的第三个参数发送。这是文档中缺少的部分。
因此,当您创建 webhook 时,您会发送:
{
"topic": "order:created",
"url": "{webhook_callback_url}",
"secret": "{secret_key}"
}
然后,每当 Printify 向您的端点发送数据时,它们都会使用该密钥对响应进行哈希处理,并将该哈希值作为 x-pfy-signature 标头发送。
就像在他们的 python 示例中一样,您必须比较哈希,而不是密钥本身。您需要使用密钥对发送到 webhook 的数据进行哈希处理,然后将您的哈希值与发送的签名进行比较。就像你描述的那样。
在 PHP 中这要容易得多,这是我用来检查签名的函数:
function validate_webhook($request, $signature): bool
{
$signature = str_replace('sha256=', '', $signature);
$hash = hash_hmac('sha256', $request, {secret_key});
return hash_equals($signature, $hash);
}
其中$request
是请求的主体,$signature
是 x-pfy-signature 标头的内容。
推荐阅读
- jquery - 带有 bodyScrollLock 的 Sidr 将页面滚动到顶部
- delphi - Delphi:反序列化 TList
使用 TJson.JsonToObject - excel - Excel - COUNTIFS 比较日期不返回任何值
- sonos - Sonos - 如何通过我的 iOS 应用在 Sonos 设备上播放 Spotify/AppleMusic 曲目?
- python - 使用 Python 和 Dask 计算欧几里得距离
- google-apps-script - 如何通过 API 访问特定视图或属性的 Google Analytics 过滤器
- ios - 在 WKWebview 中修改请求标头
- sql-server - SQL Server 不同类型的变量,$ 和@
- node.js - SailsJs,数据库查询返回一个空数组
- python - 使用 Flask 将 HTML 页面加载到 HTML 框架中