验证 Shopify 网络钩子
Verify Shopify webhook
我相信要让 Shopify webhook 与 Rails 应用程序集成,Rails 应用程序 needs to disable the default verify_authenticity_token
method, and implement its own authentication using the X_SHOPIFY_HMAC_SHA256
header. The Shopify docs 表示只需使用 request.body.read
。所以,我这样做了:
def create
verify_webhook(request)
# Send back a 200 OK response
head :ok
end
def verify_webhook(request)
header_hmac = request.headers["HTTP_X_SHOPIFY_HMAC_SHA256"]
digest = OpenSSL::Digest.new("sha256")
request.body.rewind
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, SHARED_SECRET, request.body.read)).strip
puts "header hmac: #{header_hmac}"
puts "calculated hmac: #{calculated_hmac}"
puts "Verified:#{ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, header_hmac)}"
end
Shopify webhook 被定向到正确的 URL 并且路由将其提供给上面显示的控制器方法。但是当我发送测试通知时,输出不正确。两个HMAC不相等,所以不验证。我相当确定问题在于 Shopify 正在使用整个请求作为身份验证哈希的种子,而不仅仅是 POST 内容。所以,我需要原始的、未修改的 HTTP 请求,除非我弄错了。
经过至少一个小时的搜索,This 问题似乎是 Internet 上唯一有希望的问题。这正是我要问的,它有一个被接受的答案,有 30 个赞成票。但他的回答……很荒谬。它吐出各种莫名其妙、乱七八糟的乱七八糟的东西。我是不是漏掉了一些明显的东西?
此外,this article 似乎暗示我正在寻找的东西是不可能的。似乎 Rails 从来没有得到过纯正的请求,但在到达 Rails 之前,它被 Rack 分成了不同的部分。如果是这样,我想我可能会尝试重新组装它,但我什至必须获得正确的 headers 顺序才能使哈希正常工作,所以我无法想象这是可能的。
我想我的主要问题是,我完全搞砸了吗?
您是否尝试过按照他们在指南中显示的顺序进行操作?他们有 ruby.
的工作样本
def create
request.body.rewind
data = request.body.read
header = request.headers["HTTP_X_SHOPIFY_HMAC_SHA256"]
verified = verify_webhook(data, header)
head :ok
end
他们在指南中说:
Each Webhook request includes a X-Shopify-Hmac-SHA256 header which is
generated using the app's shared secret, along with the data sent in
the request.
关键词是 "generated using shared secret AND DATA sent in the request" 所以所有这些都应该在你这边可用,包括数据和共享秘密。
问题出在我的 SHARED_SECRET 上。我认为这是 API 密钥,因为几天前它在 Shopify 管理页面中被称为共享密钥。但现在我在通知页面底部看到一个小段落,上面写着
All your webhooks will be signed with ---MY_REAL_SHARED_SECRET--- so
you can verify their integrity.
这是我需要用来验证 webhook 的秘密。为什么有两个,我也想不通。
我相信要让 Shopify webhook 与 Rails 应用程序集成,Rails 应用程序 needs to disable the default verify_authenticity_token
method, and implement its own authentication using the X_SHOPIFY_HMAC_SHA256
header. The Shopify docs 表示只需使用 request.body.read
。所以,我这样做了:
def create
verify_webhook(request)
# Send back a 200 OK response
head :ok
end
def verify_webhook(request)
header_hmac = request.headers["HTTP_X_SHOPIFY_HMAC_SHA256"]
digest = OpenSSL::Digest.new("sha256")
request.body.rewind
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, SHARED_SECRET, request.body.read)).strip
puts "header hmac: #{header_hmac}"
puts "calculated hmac: #{calculated_hmac}"
puts "Verified:#{ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, header_hmac)}"
end
Shopify webhook 被定向到正确的 URL 并且路由将其提供给上面显示的控制器方法。但是当我发送测试通知时,输出不正确。两个HMAC不相等,所以不验证。我相当确定问题在于 Shopify 正在使用整个请求作为身份验证哈希的种子,而不仅仅是 POST 内容。所以,我需要原始的、未修改的 HTTP 请求,除非我弄错了。
经过至少一个小时的搜索,This 问题似乎是 Internet 上唯一有希望的问题。这正是我要问的,它有一个被接受的答案,有 30 个赞成票。但他的回答……很荒谬。它吐出各种莫名其妙、乱七八糟的乱七八糟的东西。我是不是漏掉了一些明显的东西?
此外,this article 似乎暗示我正在寻找的东西是不可能的。似乎 Rails 从来没有得到过纯正的请求,但在到达 Rails 之前,它被 Rack 分成了不同的部分。如果是这样,我想我可能会尝试重新组装它,但我什至必须获得正确的 headers 顺序才能使哈希正常工作,所以我无法想象这是可能的。
我想我的主要问题是,我完全搞砸了吗?
您是否尝试过按照他们在指南中显示的顺序进行操作?他们有 ruby.
的工作样本def create
request.body.rewind
data = request.body.read
header = request.headers["HTTP_X_SHOPIFY_HMAC_SHA256"]
verified = verify_webhook(data, header)
head :ok
end
他们在指南中说:
Each Webhook request includes a X-Shopify-Hmac-SHA256 header which is generated using the app's shared secret, along with the data sent in the request.
关键词是 "generated using shared secret AND DATA sent in the request" 所以所有这些都应该在你这边可用,包括数据和共享秘密。
问题出在我的 SHARED_SECRET 上。我认为这是 API 密钥,因为几天前它在 Shopify 管理页面中被称为共享密钥。但现在我在通知页面底部看到一个小段落,上面写着
All your webhooks will be signed with ---MY_REAL_SHARED_SECRET--- so you can verify their integrity.
这是我需要用来验证 webhook 的秘密。为什么有两个,我也想不通。