phpish / shopify_app-skeleton

Skeleton Shopify App project using phpish/shopify
94 stars 41 forks source link

OAuth HMAC validation doesn't work since Shopify removed MD5 validation on June 1st 2016 #19

Open perenyiandras opened 8 years ago

perenyiandras commented 8 years ago

I used this great resource for the base of Shopify app, however since Shopify removed the MD5 validation on June 1st 2016 I always get an error message when I'm trying to install the app to a new stor. "Invalid Request! Request or redirect did not come from Shopify."

I read a lot about how to do the validation here: https://help.shopify.com/api/guides/authentication/oauth however when I map the received values I only have hmac, timestamp and store. No code and signature.

Anyone has a workaround for this? I appreciate any help!!!!

P.s.: I use exactly the same code uploaded here without any modification.

webserviceXXL commented 8 years ago

As quick fix you just can comment out the request validation in oauth.php

# Guard: http://docs.shopify.com/api/authentication/oauth#verification //shopify\is_valid_request($_GET, SHOPIFY_APP_SHARED_SECRET) or die('Invalid Request! Request or redirect did not come from Shopify');

But for sure then the app is less secure. So this works as a workaround but isn't fixing the problem.

myjanky commented 8 years ago

I will do a pull request when time permits. but here is a function with the meat and bones to replace function is_valid_request()

attribute to ohShopify.php

public function validateSignature($query)
    {
        if(!is_array($query) || empty($query['hmac']) || !is_string($query['hmac']))
            return false;
        $dataString = array();
        foreach ($query as $key => $value) {
            if(!in_array($key, array('shop', 'timestamp', 'code'))) continue;
            $key = str_replace('=', '%3D', $key);
            $key = str_replace('&', '%26', $key);
            $key = str_replace('%', '%25', $key);
            $value = str_replace('&', '%26', $value);
            $value = str_replace('%', '%25', $value);
            $dataString[] = $key . '=' . $value;
        }
        sort($dataString);

        $string = implode("&", $dataString);
        $signatureBin = mhash(MHASH_SHA256, $string, $this->secret);
        $signature = bin2hex($signatureBin);

        return $query['hmac'] == $signature;
    }
perenyiandras commented 8 years ago

That looks pretty good! Thanks for the help @myjanky!

myjanky commented 8 years ago

You are welcome. Goes without saying that this is for phpish/shopify and not the shopify_app_skeleton.

And $this->secret can be changed to $secret. $secret can be passed like in is_valid_request($_GET, SHOPIFY_APP_SHARED_SECRET); validateSignature($_GET, SHOPIFY_APP_SHARED_SECRET);

impupindersingh commented 8 years ago

you can use this function instead of is_valid_request() function

function is_valid_request_hmac($query_params, $shared_secret) {
 if (!isset($query_params['timestamp'])) return false;
 $seconds_in_a_day = 24  60  60;
 $older_than_a_day = $query_params['timestamp'] < (time() - $seconds_in_a_day);
 if ($older_than_a_day) return false;

 $hmac = $query_params['hmac'];
 unset($query_params['signature'], $query_params['hmac']);

 foreach ($query_params as $key=>$val) $params[] = "$key=$val";
 sort($params);

 return (hash_hmac('sha256', implode('&', $params), $shared_secret) === $hmac);
}
myjanky commented 8 years ago

@pupinder This breaks any updates from composer when the project is pushed to the server. If a developer is using this lib they will not be able to use the phpish Shopify library but instead use your unofficial repo. see https://github.com/phpish/shopify/pull/4#issuecomment-223304261

function is_valid_request($query_params, $shared_secret) { if(!is_array($query_params)) return false; if(array_key_exists('shop',$query_params) && array_key_exists('timestamp',$query_params) && array_key_exists('hmac',$query_params)) { $hmac = $query_params['hmac']; unset($query_params['signature']); unset($query_params['hmac']); ksort($query_params); return $hmac == hash_hmac('sha256', http_build_query($query_params), $shared_secret); } return false; }

alexandprivate commented 8 years ago

Hello, I am having this persistent error every time I try to install my app and this is so far the many things I have tried.

I have phpish/shopify_app-skeleton in my server and compose install with all dependencies after that I change my conf.php adding a global variable for redirecting URL:= like this

define('REDIRECT_URL', 'http://my-app-name.hosting.com/app/oauth.php');

after that in my oauth.php file I place at the end of the line 16 my gobal variable "REDIRECT_URL" like this:

$permission_url = shopify\authorization_url($_GET['shop'], SHOPIFY_APP_API_KEY, array('read_content', 'write_content', 'read_themes', 'write_themes', 'read_products', 'write_products', 'read_customers', 'write_customers', 'read_orders', 'write_orders', 'read_script_tags', 'write_script_tags', 'read_fulfillments', 'write_fulfillments', 'read_shipping', 'write_shipping'),REDIRECT_URL);

also I have commented the line 11:

shopify\is_valid_request($_GET, SHOPIFY_APP_SHARED_SECRET) or die('Invalid Request! Request or redirect did not come from Shopify');

even I have replace line 11 with the function explained in this post but not result came up.

but nothing works... any advice ??? anything else to do, I am doing something wrong o missing any steps?

athar21200 commented 7 years ago

I didn't found any file named "ohShopify.php" i am getting same error so how to fix?

myjanky commented 7 years ago

https://github.com/cmcdonaldca/ohShopify.php ohShopify is another library that may be easier to use for those who are having issues with HMAC.

pkp2409 commented 6 years ago

Easy to follow https://www.shopify.in/partners/blog/17056443-how-to-generate-a-shopify-api-token