Rails:无法匹配 json 响应中的 webhook 签名

Posted

技术标签:

【中文标题】Rails:无法匹配 json 响应中的 webhook 签名【英文标题】:Rails: Cannot match webhook signature in json response 【发布时间】:2021-10-10 10:06:46 【问题描述】:

我需要能够验证 webhook 的签名,但我似乎无法正确匹配该值。我使用的工具提供了预期的签名作为请求的 URL 参数:

YOUR_CALLBACK_URL?signature=ofdiwefjojiefwojowefoi
# www.websitename.com?signature=ofdiwefjojiefwojowefoi

他们声明他们生成签名的方式是:

使用此 Webhook 机密,使用 Webhook 帖子的原始 HTTP 正文的 HMAC-SHA-256 base64 摘要生成签名。

你可以在php中生成签名如下:

$request_body = file_get_contents('php://input');
$s = hash_hmac('sha256', $request_body, 'mySecret', true);
echo base64_encode($s);

在我的应用中,我尝试通过执行以下操作来生成匹配的签名:

key = ENV['ESIGNGENIE_SECRET']
data = params.to_json
signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, data)).strip()
return signature == params["signature"]

这似乎总是错误的。我在这里做错了吗?我不知道我是否因为 Rails 解析 json 对象的方式或其他原因而遇到问题。

【问题讨论】:

您是否尝试将两个签名打印出来进行比较,看看 rails 是如何解析它的? 是的,我有,但它们不同。 更奇怪的是,我最初使用 Hookbin 来捕获 webhook,当我使用 hookbin 中显示的主体并将其转换为字符串并执行完全相同的摘要时,我得到了正确的签名。我不明白区别 【参考方案1】:

在做了一些研究之后,我意识到我的错误是尝试使用 params 来生成签名,而我应该使用 request.body.read。它应该如下所示:

key = ENV['ESIGNGENIE_SECRET']
data = request.body.read
signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, data)).strip()
return signature == params["signature"]

【讨论】:

以上是关于Rails:无法匹配 json 响应中的 webhook 签名的主要内容,如果未能解决你的问题,请参考以下文章

当没有找到与 Rails 的 JQuery 自动完成匹配时如何显示响应

Rails 3:在 Rails 中使用 JSON 响应 REST-ful 操作的正确方法是啥?

如何在 Rails 的 JSON 响应中包含 cookie?

Rails 4 - 只响应 JSON 而不是 HTML

Restkit 无法匹配响应描述符

opsworks rails.env 与自定义 json rails_env 不匹配