2023.04.13[Thu]

Shopify アクセスモードの オフラインとオンラインを同時に使用する

  • Shopify

目次

こんにちは、Webエンジニアの永井です。

Shopify APIを利用する時に渡すアクセストークンにはオフラインとオンラインの2種類あります。
どちらかだけで問題ない場合もありますが、バックグラウンド作業にはオフライントークン、ユーザーのアプリ操作にはオンライントークン、と同時に使いたい場合も多々あると思います。

そこで今回は、アクセスモードのオフラインとオンラインを同時に使用する方法を紹介します。

環境

@shopify/app:3.44.1
@shopify/cli:3.44.1

npm init @shopify/app@latestを使用して、nodeで構築しています。(2023年3月現在)

アクセスモードとは

Shopify APIのアクセストークン作成時に指定するモードのことで、オフラインとオンラインの2種類あります。

オフラインモード

オフラインモードのトークンは、有効期限がないのが特徴です。
ユーザーの操作が関与しないバックグラウンド作業などに適しています。

オンラインモード

オンラインモードのトークンは、ストアの個々のユーザーに紐づけられ、有効期限があることが特徴です。
ログインユーザーがWebからアプリを操作する場合などに適しています。

アクセスモードの指定方法

アクセスモードは明示的に指定しない場合、デフォルトでオフラインモードが設定されます。
オンラインモードと同時に使用する場合には、shopifyAppの関数にuseOnlineTokensを追加する必要があります。

// /web/shopify.js

import { shopifyApp } from "@shopify/shopify-app-express";
...

const shopify = shopifyApp({
...
  // ⭐️ 追加
  useOnlineTokens: true,
});

動作確認

アクセストークンは「セッション」として自動的に保存されます。
セッションの保存先は、shopifyApp関数のsessionStorageで設定が可能です。
環境構築からコードを変更していない場合、SQLiteが設定されています。

// /web/shopify.js

import { shopifyApp } from "@shopify/shopify-app-express";
import { SQLiteSessionStorage } from "@shopify/shopify-app-session-storage-sqlite";
...

const DB_PATH = `${process.cwd()}/database.sqlite`;
...

const shopify = shopifyApp({
...
  // ⭐️ SQLiteが指定されている
  // This should be replaced with your preferred storage strategy
  sessionStorage: new SQLiteSessionStorage(DB_PATH),
});

動作確認では、「SQLでデータ表示」と「コードでセッション取得」を行います。

オフラインモード(useOnlineTokensを指定しない場合)

SQLでデータ表示
テーブルshopify_sessionsに保存されているので、そちらのデータを取得します。
オフラインモードのセッションのみが保存されていることが分かります。

sqlite> select * from shopify_sessions;
id|shop|state|isOnline|expires|scope|accessToken|onlineAccessInfo
offline_xxx.myshopify.com|xxx.myshopify.com|564188586458978|0||write_products|shpua_xxxxxxxxxx|

コードでセッション取得
確認用で/api/products/countにコードを追加します。
セッションIDを返す関数を使用してIDを取得し、そのIDでストレージからセッションを読み込みます。

app.get('/api/products/count', async (_req, res) => {
  const sessionId = await shopify.api.session.getCurrentId({
    isOnline: false,
    rawRequest: _req,
    rawResponse: res,
  });
  const sessionStorage = new SQLiteSessionStorage(DB_PATH);
  const session = await sessionStorage.loadSession(sessionId ?? '');
...

// {
//   session: Session {
//     id: 'offline_xxx.myshopify.com',
//     shop: 'xxx.myshopify.com',
//     state: '564188586458978',
//     isOnline: false,
//     scope: 'write_products',
//     accessToken: 'shpua_xxxxxxxxxx'
//   }
// }

オンラインモード(useOnlineTokensを指定した場合)

SQLでデータ表示
オフラインモードとオンラインモードの2つのセッションが保存されていることを確認できます。

sqlite> select * from shopify_sessions;
id|shop|state|isOnline|expires|scope|accessToken|onlineAccessInfo
offline_xxx.myshopify.com|xxx.myshopify.com|711944287872451|0||write_products|shpua_xxxxxxxxxx|
xxx.myshopify.com_78556496101|xxx.myshopify.com|454938086210355|1|1679641538|write_products|shpua_xxxxxxxxxx|78556496100.0

コードでセッション取得
オフライン時のコードからisOnline: trueに変更します。
オンラインの場合、有効期限紐づいているユーザーの情報も含まれてきます。

app.get('/api/products/count', async (_req, res) => {
  const sessionId = await shopify.api.session.getCurrentId({
    isOnline: true,
    rawRequest: _req,
    rawResponse: res,
  });
  const sessionStorage = new SQLiteSessionStorage(DB_PATH);
  const session = await sessionStorage.loadSession(sessionId ?? '');
...

// {
//   session: Session {
//     id: 'xxx.myshopify.com_78556496101',
//     shop: 'xxx.myshopify.com',
//     state: '454938086210355',
//     isOnline: true,
//     expires: 2023-03-24T07:05:39.000Z,
//     scope: 'write_products',
//     accessToken: 'shpua_xxxxxxxxxx',
//     onlineAccessInfo: { associated_user: [Object] }
//   }
// }

まとめ

アクセスモードのオフラインとオンラインを同時に使用する方法を紹介しました。
Shopify開発時の参考になれば幸いです。

Share

SpeedCurve 利用例 概要編JestでspyOn関数を使って、windowをモックする方法