在 Ruby 中匹配 Square Webhook 签名(在 Rails 上)

Matching Square Webhook signature in Ruby (on Rails)

我正在尝试匹配 X-Square-Signature header,如此处记录:https://docs.connect.squareup.com/api/connect/v1/#validating-notifications

我目前正在使用 OpenSSL::HMAC 生成摘要,但似乎不正确。

string_to_sign = "#{request.url}#{param_hash.to_json}"
header_signature = request.headers["X-Square-Signature"]

# split into multiple lines for clarity
digest = OpenSSL::Digest.new('sha1')
hmac = OpenSSL::HMAC.digest(digest, ENV["SIGNATURE_KEY"], string_to_sign)

# stripping the newline off the end
hmac_64 = Base64.encode64(hmac).strip

出于某种原因,尽管遵循了上面 API 文档中提供的说明,但我得到了截然不同的摘要。我对摘要的计算似乎也符合他们的 python 示例 (https://github.com/square/connect-api-examples/blob/master/connect-examples/v1/webhooks.py#L75-L87)。

我已验证 string_to_sign 值与我应该遵循的模式相同,当我手动制作 post 时它有效,但我通过相同的方法生成我的签名所以当然是排队了。

我可能会忽略 digest/signature 计算过程的任何细节吗?

听起来您正在尝试复制 Square 文档中的示例。您提到您验证了 string_to_signhttp://www.example.com{"merchant_id":"JGHJ0343","event_type":"PAYMENT_UPDATED","entity_id":"Jq74mCczmFXk1tC10GB"},但是您是否验证了环境变量 SIGNATURE_KEY 是文档中的 EXAMPLE_SECRET_123

您使用替换值和设置环境变量编写的代码计算示例中给出的散列:DBP9woNqJpO4d4/ZFE7xveLIGPU=

我不确定这是否是您问题的根源,但您应该使用 request.raw_post 而不是 param_hash.to_json。请求正文是一个 json 对象,json 对象的属性没有规范的排序。当您将参数哈希转换回 json 时,无法保证属性的顺序与原始请求正文中的顺序相同。

使用

重试
string_to_sign = "#{request.url}#{request.raw_post}"