Убедитесь, что посещение страницы настроек встроенного приложения осуществляется из Shopify в PHP - PullRequest
0 голосов
/ 30 августа 2018

Когда клиент устанавливает приложение, у него есть возможность нажать на название приложения в списке приложений на странице /admin/apps.

Когда они нажимают эту страницу, мой индексный файл PHP для моего приложения получает $_GET vars:

hmac = some_long_alphanumaeric_hmac
locale = en
protocol = https://
shop = example-shop.myshopify.com
timestamp = 1535609063

Чтобы подтвердить веб-крючок от Shopify, я успешно использую это:

function verify_webhook($data, $hmac_header, $app_api_secret) {
    $calculated_hmac = base64_encode(hash_hmac('sha256', $data, $app_api_secret, true));
    return ($hmac_header == $calculated_hmac);
}

// Set vars for Shopify webhook verification
$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header, MY_APP_API_SECRET);

Можно ли проверить, что посещение страницы администратора приложения происходит с клиента Shopify, на котором установлено приложение?

PS: я просмотрел оба, API встраиваемых приложений (но я не могу понять, правильная ли это документация или я что-то не так делаю), а также Предоставлен пример GitHub (в котором нет инструкций по проверке посещения страницы администратора встроенного приложения).

UPDATE:

Я пробовал другие способы, обнаруживая на этом пути нелепые проблемы, но все же не повезло.

  1. Метод, который я понимаю, должен использоваться для проверки Shopify HMAC, что-то вроде этого:

    function verify_hmac($hmac = NULL, $shopify_app_api_secret) {
        $params_array = array();
        $hmac = $hmac ? $hmac : $_GET['hmac'];
        unset($_GET['hmac']);
    
        foreach($_GET as $key => $value){
            $key = str_replace("%","%25",$key);
            $key = str_replace("&","%26",$key);
            $key = str_replace("=","%3D",$key);
            $value = str_replace("%","%25",$value);
            $value = str_replace("&","%26",$value);
            $params_array[] = $key . "=" . $value;
        }
    
        $params_string = join('&', $params_array);
        $computed_hmac = hash_hmac('sha256', $params_string, $shopify_app_api_secret);
    
        return hash_equals($hmac, $computed_hmac);
    }
    

Но строка $params_string = join('&', $params_array); вызывает досадную проблему, кодируя &timestamp как xtamp ... Использование http_build_query($params_array) приводит к той же нелепой вещи. Нашли другие, имеющие такую ​​же проблему здесь . В основном решается путем кодирования & как &, чтобы получить $params_string = join('&', $params_array);.

  1. Моя окончательная версия похожа на эту, но все еще не работает (весь закомментированный код - это то, что я пытался безрезультатно):

    function verify_hmac($hmac = NULL, $shopify_app_api_secret) {
        $params_array = array();
        $hmac = $hmac ? $hmac : $_GET['hmac'];
        unset($_GET['hmac']);
    //  unset($_GET['protocol']);
    //  unset($_GET['locale']);
    
        foreach($_GET as $key => $value){
            $key = str_replace("%","%25",$key);
            $key = str_replace("&","%26",$key);
            $key = str_replace("=","%3D",$key);
            $value = str_replace("%","%25",$value);
            $value = str_replace("&","%26",$value);
            $params_array[] = $key . "=" . $value;
    //  This commented out method below was an attempt to see if 
    //  the imporperly encoded query param characters were causing issues
    /*
            if (!isset($params_string) || empty($params_string)) {
                $params_string = $key . "=" . $value;
            }
            else {
                $params_string = $params_string . "&" . $key . "=" . $value;
            }
    */
        }
    
    //  $params_string = join('&', $params_array);
    //  echo $params_string;
    //  $computed_hmac =  base64_encode(hash_hmac('sha256', $params_string, $shopify_app_api_secret, true));
    //  $computed_hmac =  base64_encode(hash_hmac('sha256', $params_string, $shopify_app_api_secret, false));
    //  $computed_hmac =  hash_hmac('sha256', $params_string, $shopify_app_api_secret, false);
    //  $computed_hmac =  hash_hmac('sha256', $params_string, $shopify_app_api_secret, true);
        $computed_hmac = hash_hmac('sha256', http_build_query($params_array), $shopify_app_api_secret);
    
        return hash_equals($hmac, $computed_hmac);
    }
    

1 Ответ

0 голосов
/ 30 августа 2018

Если вы получаете удар от Shopify, в первую очередь вы проверяете свой уровень персистентности, если у вас есть зарегистрированный магазин. Если вы это сделаете, и у вас есть сеанс какой-то настройки, вы можете представить свое приложение в этом магазине. Если магазин не был сохранен, вы проходите цикл oAuth, чтобы получить токен аутентификации для использования в магазине, который сохраняется вместе с магазином и новым сеансом.

Для любых маршрутов или конечных точек в вашем магазине, где вы получаете веб-хук, конечно, эти запросы не имеют сеанса, поэтому вы используете подход безопасности HMAC, чтобы выяснить, что делать. Таким образом, ваш вопрос явно охватывает два разных понятия, каждое из которых обрабатывается по-разному. Документация довольно ясно о различиях.

...