【问题标题】:Verify Shopify webhook验证 Shopify 网络钩子
【发布时间】:2017-06-23 20:55:25
【问题描述】:

我相信,要将 Shopify webhook 与 Rails 应用程序(Rails 应用程序needs to disable the default verify_authenticity_token method)集成,并使用 X_SHOPIFY_HMAC_SHA256 标头实现自己的身份验证。 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 问题经过至少一个小时的搜索,似乎是互联网上唯一有希望的事情。这正是我要问的,它有一个接受的答案,有 30 个赞成票。但他的回答……是荒谬的。它吐出一堆乱七八糟的乱七八糟的东西。我错过了什么明显的东西吗?

此外,this article 似乎暗示我正在寻找的东西是不可能的。似乎 Rails 从来没有收到过纯粹的请求,但它在到达 Rails 之前就被 Rack 分成不同的部分。如果是这样,我想我可能会尝试重新组装它,但我什至必须让标题的顺序正确才能使哈希起作用,所以我无法想象这是可能的。

我想我的主要问题是,我完全搞砸了吗?

【问题讨论】:

    标签: ruby-on-rails http http-post shopify webhooks


    【解决方案1】:

    问题出在我的 SHARED_SECRET 中。我认为这是 API 密钥,因为几天前它在 Shopify 管理页面中被称为共享密钥。但现在我在通知页面底部看到一小段文字,

    您的所有 webhook 都将使用 ---MY_REAL_SHARED_SECRET--- 进行签名,所以 您可以验证它们的完整性。

    这是我需要用来验证 webhook 的秘密。为什么有两个,我不知道。

    【讨论】:

    • 嘿,我也遇到了同样的问题,你从哪里弄来的这把钥匙?我正在创建一个公共应用程序,而不仅仅是发送一个存储的 webhook,这是你在做什么吗?
    • 我正在创建一个公共应用程序并构建一个 webhook。我将应用程序的 API 密钥与 webhook 的共享密钥混淆了。我相信 API 密钥在 Shopify 管理页面中,而 webhook 密码在通知页面的底部。至少,这在 6 个月前是正确的。
    【解决方案2】:

    您是否尝试过按照指南中显示的顺序进行操作?他们有一个 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
    

    他们在指南中说:

    每个 Webhook 请求都包含一个 X-Shopify-Hmac-SHA256 标头,该标头是 使用应用程序的共享密钥生成,以及发送的数据 请求。

    密钥是“使用请求中发送的共享密钥和数据生成的”,因此所有这些都应该在您端可用,包括数据和共享密钥。

    【讨论】:

    • 我写它的顺序应该没有关系,但我还是尝试了指南的确切顺序,它仍然不起作用。 “数据”一词似乎表明它只是请求正文,但事实仍然是我的代码没有产生与它们相同的哈希值。这就是为什么我认为它意味着整个原始请求,包括标头。
    • @tschwab,你试过用 .body 代替 .body.read 吗?
    • 另外,有一次,当编码为 base64 时,我必须在编码之前对内容进行 .gsub("\n", '') 。也试试里面有条,不带条?
    • body返回一个输入流,body.read返回一个字符串的body内容,所以肯定是body.read。我试过不带带,带内带,带内和外带,gsub() 在内容上,gsub 不带带,以及其他一些。都没有奏效。我只是想出了一个系统的方法来测试每一种可能性,所以我将继续尝试迭代。会不会是 OpenSSL 的版本差异问题?
    • @tschwab - 我不这么认为,但您可以尝试更新 gem。此外,您似乎不需要 Rails >= 3 中的 .body.rewind ,这是专门针对 sinatra 的。而且,虽然这不应该是问题:OpenSSL::Digest.new("sha256") - 尝试使用 OpenSSL::Digest::Digest.new('sha256')
    猜你喜欢
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多