【问题标题】:Verify Shopify webhook with many possible secrets使用许多可能的秘密验证 Shopify webhook
【发布时间】:2017-07-25 01:04:07
【问题描述】:

我创建了一个仪表板,用于汇总多个 Shopify 商店的订单处理。这是一个私人应用程序,因此我将每个 Shopify 商店的 API 凭据和 webhook 密码保存在我的数据库中。我已经使用存储为环境变量的密钥加密了所有这些敏感内容。对于任何给定事件,我将所有 Shopify 商店定向到相同的回调 URL。因此,对于每个 url,我必须根据存储在数据库中的所有可能的 webhook 机密来验证请求正文。我有两个问题:

  1. 这是一种可以接受的方法来保护商店的 API 凭据和 webhook 机密吗?
  2. 如果我的秘密存储在数据库中,如何同步验证请求正文?我的验证功能如下。

  verify: (buffer, hmacHeader) => {
    Brand.find().exec((err, brands) => {
      if (!err && brands) {
        const allWebhookSecrets = brands.map(brand => {
          console.log(`encrypted webhook secret is: ${brand.shopify_webhook_secret_encrypted}`)
          return encryption.decrypt(brand.shopify_webhook_secret_encrypted);
        });
        const webhookIsValid = allWebhookSecrets.some(secret => {
          var hmac = crypto.createHmac('sha256', secret)
            .update(buffer)
            .digest('base64');
          return hmac == hmacHeader;
        });
        console.log(`webhookIsValid: ${webhookIsValid}`);
        return webhookIsValid;
      }
      return false;
    });
  }

【问题讨论】:

    标签: javascript security shopify webhooks


    【解决方案1】:

    通常,您真正应该在数据库中存储的唯一内容是应用程序的商店访问令牌和商店登录的任何其他验证数据。每次使用您的应用程序共享密钥和 Webhook 即将发送给您的数据向您的应用程序发送请求时,Webhook 签名和生成的方式都会有所不同。

    Webhook 使用您的应用程序共享密钥和在标头中发送到 HMAC 签名的发布请求数据进行验证:X-Shopify-Hmac-SHA256

    这是我对 webhook 验证中间件的简化 nodejs 实现

    function verify_webhook(postData, hmac) {
        if (!hmac || !postData || typeof postData !== 'object') {
          return false;
        }
    
        const calculatedSignature = crypto.createHmac('sha256', process.env.SHOPIFY_SHARED_SECRET)
        .update(postData)
        .digest('hex');
        return calculatedSignature === hmac;
      }
    

    其中 postData 和 hmac 是 JSON.stringify(req.body)req.get('X-Shopify-Hmac-SHA256')

    通常没有必要将这些信息存储在数据库中,然后使用中间件即时计算和验证。我希望这会有所帮助。

    【讨论】:

    • 我实际上并没有将签名存储在数据库中,只是连接到应用程序的不同商店的不同秘密。我不能将这些秘密存储为环境变量,因为存储是动态删除和添加的。所以我想知道将秘密作为纯文本存储在数据库中是否是个好主意。
    • 关于验证码,由于secret是存储在数据库中的,所以需要异步检索。要中止缓冲区的处理(拒绝 webhook 请求),可能会引发错误,但在异步数据库调用之后我仍然可以引发错误吗?
    猜你喜欢
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    相关资源
    最近更新 更多