Entersquare Inc. ホームページ作成の株式会社エンタースクウェア

【Shopify】Admin APIをPHPクライアントライブラリで使う

【Shopify】Admin APIをPHPクライアントライブラリで使う

ShopifyのAdmin APIをPHPで利用したいプロジェクトがありました。

Shopifyのドキュメントの通りPHP用のライブラリを入れたのですが、OAuth認証がどうしてもできず、カスタマイズしたのでメモとして残しておきます。

つい最近GraphQL Admin API referenceからPHPがなくなったので、他の使ってよという事かもしれないのですが。

ひとつ目の上手くいかなかったところから。

OAuth::begin()で正いURLが生成されない

$authUrl = OAuth::begin($shop, $redirectUri, $isOnline);
このOAuth:begin()でOAuthのURLが生成される想定なのですが、パスが重なってどうも上手く生成されません。
しょうがないのでこれは使わずに、URLを書いて作ります。
  $authUrl = "https://".env('SHOPIFY_APP_HOST_NAME')."/admin/oauth/authorize?client_id=".env('SHOPIFY_API_KEY')."&scope=".env('SHOPIFY_SCOPES')."&redirect_uri=".$redirectUrl."&state=".$state;

Shopify キー等はenvで指定しています。

次に上手くいかないこと。

リダイレクトで戻ってきた時にCOOKIEのエラーが出る

You may have taken more than 60 seconds to complete the OAuth process and need to start over in..

とCOOKIEのエラーが出ます。

そもそもこのエラーの場合はエラー内容の通りにリダイレクトまでに時間がかかっているよ、という事で、本当に時間がかかっているか、もしくはサーバーの時間がおかしいかのどちらかになります。

そういったエラーかと思っていたのですが、調査していくとどうやらOAuth::begin()を使っていないせいで、必要なCOOKIEが生成されてないのがひとつ。

仕方がないのでCOOKIEは自作します。

OAuthに必要なCOOKIEを自作する

このコードはLaravel11で作っていますのでLaravel用の関数が含んでいるかもしれません。ご容赦ください。

//Cookieは自作する
// 1. Shopify App State(CSRF保護用stateトークン)の生成と保存
$state = bin2hex(random_bytes(16));

// stateトークンをクッキーに保存
$cookies[] = cookie('shopify_app_state', $state, 60, '/', null, true, true);

// stateトークンの署名(sig)を生成
$stateSig = hash_hmac('sha256', $state, env('SHOPIFY_API_SECRET'));

// state署名をクッキーに保存
$cookies[] = cookie('shopify_app_state_sig', $stateSig, 60, '/', null, true, true);


// -------------------------------
// 2. Shopify Session IDの生成と保存
$sessionId = session_id();  // PHPのセッションIDを取得

// セッションIDをクッキーに保存
$cookies[] = cookie('shopify_session_id', $sessionId, 60, '/', null, true, true);

// セッションIDの署名(sig)を生成
$sessionSig = hash_hmac('sha256', $sessionId, env('SHOPIFY_API_SECRET'));

// セッションID署名をクッキーに保存
$cookies[] = cookie('shopify_session_id_sig', $sessionSig, 60, '/', null, true, true);

//State
$cookies[] = cookie('shopify_state', $state, 60, '/', null, true, true);

$stateは先ほどのURL生成の一番後ろにある$stateです。

もしくはライブラリでOAuth::begin()を修正してしまう

shopify/shopify-api/src/Auth/OAuth.php

53行目のこれを

'redirect_uri' => Context::$HOST_SCHEME . '://' . Context::$HOST_NAME

こっちに↓

'redirect_uri' => $redirectPath,

リダイレクトで戻ってきた時にも正く必要な値でCOOKIEに入っていることが確認できます。

しかし、どうしても先ほどのエラーで進みません。

しょうがないのでライブラリの中身を見ていると、COOKIEのexpires(期日)の取得がうまくいってないようなので、ライブラリをちょっと編集します。

Auth/OAuth.phpを修正する

shopify/shopify-api/src/Auth/OAuth.php

155行目のこれを

$sessionExpiration = ($session->getExpires() ? (int)$session->getExpires()->format('U') : 0);

次のように、0をnullにする

 $sessionExpiration = ($session->getExpires() ? (int)$session->getExpires()->format('U') : null);

修正したとことでアプリを削除し再度認証を行います。

この修正で無事OAthが完了しました。

Solutions

ソリューション

ホームページ作成

Webサイト制作・運用保守

コーポレートサイト/サービスサイト/オウンドメディアサイト/LP/EC

ウェブマーケティングの技術を使ってホームページの作成や保守を承っております。

Webのお悩み

Webのご相談・サポート

運用のお困りごと/集客のお困りごと/運用担当が居なくなったなど

Webに関するお困りごとや、お悩みなどのご相談、サポートを承っております。

その他、アクセス解析、広告運用、SNSサポートなどWebに関する事全般承っております。

詳しく見る