I’m trying to validate the requests coming from Shopify but I’m unable to do so.
Here’s the code I’m using to get the hmac hash from the request (from here):
A protocol=http:// or https:// needs to be added to the message
$params = $request;
unset($params['signature']);
unset($params['hmac']);
$collected = array_map(function($key, $value) {
return $key . "=" . $value;
}, array_keys($params), $params);
asort($collected);
$collected = implode('&', $collected);
$shared_secret = 'MySecretHere';
return hash_hmac('sha256', $collected, $shared_secret);
I’m even following the example provided in https://docs.shopify.com/api/authentication/oauth#verification
$message = 'shop=some-shop.myshopify.com×tamp=1337178173';
$secret = "hush";
var_dump(hash_hmac('sha256', $message, $secret), "2cb1a277650a659f1b11e92a4a64275b128e037f2c3390e3c8fd2d8721dac9e2"); die();
the hash resulting from that code is: c2812f39f84c32c2edaded339a1388abc9829babf351b684ab797f04cd94d4c7
I have run the same example using ruby (as you suggest on the docs page), creating a file called ‘hmacruby’ with:
require 'openssl'
digest = OpenSSL::Digest.new('sha256')
secret = "hush"
message = "shop=some-shop.myshopify.com×tamp=1337178173"
digest = OpenSSL::HMAC.hexdigest(digest, secret, message)
p digest
using the command line went to the same folder where that file is stored in and run:
$ ruby hmacruby
the result was: c2812f39f84c32c2edaded339a1388abc9829babf351b684ab797f04cd94d4c7
I also have tested the algorithm here and I’m having the same result. What is going on?
SOLUTION:
As Zelf is pointing out here:
post app install, Shopify will no longer send the “code” parameter that the docs refer to. In fact now they send a “protocol” parameter, which is not in the docs. However, the docs are still correct, you need to grab all parameters and remove signature and hmac, then whatever is left over, simply sort lexicographically, then hash_hmac with secret token like in the code example above.
After install, adding "protocol=https://&"; to the beginning of the message works. so the entire message NEEDS TO HAVE every param received from Shopify + the protocol (which should be 'https://'), which should be added first thing.
"protocol=https://&shop=yourshop.myshopify.com×tamp=1439924556"; including ‘protocol=’