2017-07-25 59 views
1

我創建了一個儀表板,彙總​​了多個Shopify商店的訂單處理。這是一個私人應用程序,因此我將每個Shopify商店的API憑據和webhook祕密保存在我的數據庫中。我用一個存儲爲環境變量的密鑰加密了所有這些敏感的東西。對於任何特定活動,我指示所有Shopify商店都使用相同的回叫網址。因此,對於每個網址,我必須驗證請求主體是否存儲在數據庫中的所有可能的webhook祕密。我有兩個問題:驗證Shopify 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; 
 
    }); 
 
    }

回答

0

通常你應該在你的數據庫中存儲的唯一事情就是店鋪,爲您的應用程序和商店登錄任何其他驗證數據的訪問令牌。每次向您的應用程序發送請求時,都會使用您的應用程序共享密鑰以及webhook將要發送給您的數據,Webhook簽名和生成方式會有所不同。

Webhooks使用您的應用程序共享密鑰和發送請求數據到標頭中發送的HMAC簽名進行驗證:X-Shopify-Hmac-SHA256

這是我簡單的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')

有一般不點在數據庫中存儲這些信息,只是計算它和驗證它使用中間件即時進行。我希望這有幫助。

+0

我實際上並沒有在數據庫中存儲簽名,只是連接到應用程序的不同商店的不同祕密。由於存儲被刪除並動態添加,因此我無法將這些機密存儲爲環境變量。所以我想知道如果將數據庫中的祕密存儲爲純文本是個好主意。 –

+0

至於驗證碼,由於祕密存儲在數據庫中,它們必須異步檢索。要中止緩衝區的處理(拒絕webhook請求),可能會拋出錯誤,但是在異步數據庫調用之後仍然可以拋出錯誤嗎? –