Shopify App 使用 OAuth 2 進行商家認證和授權

在現在的程式開發語言或框架,可能能夠找到現有的函式庫來快速打造出需要的功能,避免自己編寫過多的程式,但在遭遇問題處理時可能往往會不知道背後的運作流程,所以寫了這篇文章來記錄了解 Shopify 的 OAuth 身份驗證流程的工作原理。

首先建立一個應用程式,獲得 API key 與 API secret key,並在 App 設定中提供 App URL 與允許的重新導向網址。

簡敘什麼是 OAuth2?

根據官方 OAuth 描述:OAuth 2.0 是用於授權的行業標準協議。OAuth 2.0 專注於客戶端開發人員的簡單性,同時為 Web 應用程序、桌面應用程序、移動電話和客廳設備提供特定的授權流程。

它是一種身份驗證和授權訪問權限的方式,網路上的用戶可以在訪問他們在其他網站上的資料,而不需要提供他們的帳戶資料(用戶名/密碼)。

Shopify OAuth 流程

OAuth 流程中處理的步驟:

  1. 商家發送安裝應用程式的請求
  2. 將權限請求導向回 shopify
  3. 商家確認授權頁面
  4. shopify 向應用程式返回確認結果
  5. 將結果再次發送回 Shopify 獲取永久 access token

1.商家發送安裝應用程式的請求

當商家訪問我們的應用程式時,Shopify 會導向並傳遞幾個額外的參數到我們設定的 App URL。

https://app.domain.dev/?hmac=93cf7b063bae0790b74bb0a34e8e5b78e997de8ae771202f3bcd71f504d6d68e&shop=store.myshopify.com&timestamp=1634909927

收到請求時首先進行 hmac 驗證來確保是來自 shopify 的請求。取得 hmac 參數以外的參數組成字串,使用 sha256 加密算法取得 hexdigest 並驗證是否與 hmac 參數一致。

PHP code example

$ary = [];
$hmac = $_GET['hmac'];
unset($_GET['hmac']);

foreach($_GET as $key => $value) {
    $ary[] = $key."=".$value;
}

$str = join('&', $ary);
$ver_hmac =  hash_hmac('sha256', $str, "APP-SECRET-KEY", false);

if($ver_hmac == $hmac)
{
    echo 'hmac verified';
}

2.將權限請求導向回 shopify

現在已經完成請求的真實性,再將該請求的參數信息結合起來構建一個 ****URL 向商家取得授權。

https://store.myshopify.com/admin/oauth/authorize?client_id=080cceb67cdeebfd96390a4d59c66fc1&redirect_uri=https%3A%2F%2Fapp.domain.dev%2Fauth%2Fshopify%2Fcallback&scope=read_products%2Cwrite_products&state=aaf4d88ef34fdc39c951d1864b627fdb65b9e719
  • client_id:應用程式的 API key
  • redirect_uri:在商家授權應用程式的權限請求後,shopify 會將頁面導向該網址。此 URL 需要與App 設定中提供的重新導向網址一致
  • scope:應用程式被授予的權限, shopify 會提示商家查看權限授權範圍
  • state:每個權限 URL 需要創建的隨機值,再 shopify 返回確認結果時必須檢查此值是否一致

3.商家確認授權頁面

當應用程式把所需要的授權訊息導向回去時, shopify 會提示應用程式所需要授予的權限。

4.shopify 向應用程式返回確認結果

商家點擊 "安裝應用程序" 這時候 shopify 會將頁面在重新導向至我們再第二個步驟所帶入的 redirect_uri ,並且傳遞幾個額外的參數讓我們再次驗證。

https://app.domain.dev/auth/shopify/callback?code=04353d50220ae434b065224421480b90&hmac=cfdcc94094bd645d012281c4071dd27b504690732751bdc3187a622e78d08303&host=dGVzdC1lcmljeHh4Lm15c2hvcGlmeS5jb20vYWRtaW4&shop=store.myshopify.com&state=aaf4d88ef34fdc39c951d1864b627fdb65b9e719&timestamp=1634977849
  • code:可以使用它來交換商家權限的永久 API access code
  • hmac:與第一個步驟一樣通過計算 HMAC SHA256 digest,來驗證請求的真實性
  • state:確認在第二個步驟所提供的隨機值是否與返回的請求一致
  • shop:商家資料

5.將結果再次發送回 Shopify 獲取永久 access token

透過 Shopify API 來交換我們最終所需要的永久 access token。

PHP code example

$query = [
  "client_id" => $api_key, 
  "client_secret" => $shared_secret, 
  "code" => $params['code'] 
];

$access_token_url = "https://" . $params['shop'] . "/admin/oauth/access_token";

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $access_token_url);
curl_setopt($ch, CURLOPT_POST, count($query));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
$result = curl_exec($ch);
curl_close($ch);

$result = json_decode($result, true);
$access_token = $result['access_token'];

此 access token 則具有我們在第 2 步驟中所請求的權限範圍。我們現在可以使用它代表商店所有者向 Shopify API 發出請求進行查閱或異動資料。