4

Shopify から Webhook リクエストを受信するエンドポイントをセットアップしました。

Shopify からのリクエストには、共有秘密鍵とリクエストの本文から作成された HMAC ヘッダーが含まれます。

サーバーで HMAC を計算し、それをリクエスト ヘッダーの値と照合して、リクエストが本物であることを確認する必要があります。

一致する HMAC 値を作成するための適切なメカニズムを .NET で作成できないようです。

この時点での私のアルゴリズムは次のとおりです。

public static string CreateHash(string data)
    {
        string sharedSecretKey = "MY_KEY";

        byte[] keyBytes = Encoding.UTF8.GetBytes(sharedSecretKey);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);

        //use the SHA256Managed Class to compute the hash
        System.Security.Cryptography.HMACSHA256 hmac = new HMACSHA256(keyBytes);
        byte[] hmacBytes = hmac.ComputeHash(dataBytes);

        //retun as base64 string. Compared with the signature passed in the header of the post request from Shopify. If they match, the call is verified.
        return System.Convert.ToBase64String(hmacBytes);
    }

Webhook を検証するための Shopify ドキュメントはこちらにありますが、含まれているのは PHP と Ruby のサンプルのみです。

誰かが私が間違っているかもしれないことを見ることができますか? JSON リクエスト本文全体を文字列としてこのメ​​ソッドに渡す必要がありますか?

4

4 に答える 4

7
    private static bool Validate(string sharedSecretKey)
    {
        var data = GetStreamAsText(HttpContext.Current.Request.InputStream, HttpContext.Current.Request.ContentEncoding);
        var keyBytes = Encoding.UTF8.GetBytes(sharedSecretKey);
        var dataBytes = Encoding.UTF8.GetBytes(data);

        //use the SHA256Managed Class to compute the hash
        var hmac = new HMACSHA256(keyBytes);
        var hmacBytes = hmac.ComputeHash(dataBytes);

        //retun as base64 string. Compared with the signature passed in the header of the post request from Shopify. If they match, the call is verified.
        var hmacHeader = HttpContext.Current.Request.Headers["x-shopify-hmac-sha256"];
        var createSignature = Convert.ToBase64String(hmacBytes);
        return hmacHeader == createSignature;
    }

    private static string GetStreamAsText(Stream stream, Encoding encoding)
    {
        var bytesToGet = stream.Length;
        var input = new byte[bytesToGet];
        stream.Read(input, 0, (int)bytesToGet);
        stream.Seek(0, SeekOrigin.Begin); // reset stream so that normal ASP.NET processing can read data
        var text = encoding.GetString(input);
        return text;
    }
于 2014-02-14T02:55:18.567 に答える
2

質問で示唆しているように、メソッド内の json リクエスト本文全体をハッシュする必要があります。

私の .NET はあまり良くありませんが、何をすべきかを示す ruby​​ の例の一部を以下に示します。

post '/' do

  . . .

  data = request.body.read
  verified = verify_webhook(data, env["HTTP_X_SHOPIFY_HMAC_SHA256"])

  . . .

end

リクエストの本文を (文字列として) 取得し、verbatim メソッドにスローしているだけであることがわかります。試してみてください。うまくいけば、より多くの運が得られます。

于 2012-11-08T14:08:01.437 に答える