Open4

Shopifyアプリのサンプル実装の認証について

t-yngt-yng

認証のフロー

https://shopify.dev/apps/auth/oauth

U: ユーザー, A: システム, S: Shopify

U: ShopifyアプリのインストールURLのアクセス(/auth?shop=<ユーザーのshopi_id>)
S: Shopifyにリダイレクト
A: ユーザーにアプリの実行権限を提示
U: アプリの実行権限を確認してOKなら承認する
S: Shopifyにアクセストークンを要求
A: ユーザーのアクセストークンを返す
S: アクセストークンで必要な情報をShopifyにリクエストする
S: アプリの画面にリダイレクトする
U アプリを使い始める

画像の 2 ~ 6 については SDK の createShopifyAuth が内部的に処理している。

t-yngt-yng

createShopifyAuth の中身

https://github.com/Shopify/koa-shopify-auth/blob/master/src/auth/index.ts

アプリを始めてインストールする場合

  1. アプリインストールのパス(/auth?shop=)にアクセスすると、認証用のページ(/auth/inline?shop=)にリダイレクトする
  2. ユーザーが権限を確認してアプリを承認
  3. Shopify側で認証が実行されコールバックURL(/auth/callback?shop=)にリクエストが来る
  4. 認証トークンの有効性をチェック後に引数で指定された afterAuth のコールバック関数を実行する。

アプリがインストール済みの場合

  1. アプリに認証リクエスト(/auth?shop=)があった場合に、認証用のパス(/auth/inline?shop=)にリダイレクトする
  2. Shopify側で店舗を認証後にコールバックURL(/auth/callback?shop=)にリクエストが来る
  3. 認証トークンの有効性をチェック後に引数で指定された afterAuth のコールバック関数を実行する。
t-yngt-yng

認証後の処理

  • メモリで保持している有効な店舗一覧に認証した店舗を追加する。
  • アプリがアンインストールされた時のコールバック処理を登録
    • メモリの有効な店舗一覧から店舗を削除
  • アプリの画面にリダイレクトする
  server.use(
    createShopifyAuth({
      async afterAuth(ctx) {
        // Access token and shop available in ctx.state.shopify
        const { shop, accessToken, scope } = ctx.state.shopify;
        const host = ctx.query.host;
        ACTIVE_SHOPIFY_SHOPS[shop] = scope;

        const response = await Shopify.Webhooks.Registry.register({
          shop,
          accessToken,
          path: "/webhooks",
          topic: "APP_UNINSTALLED",
          webhookHandler: async (_topic, shop) => {
            delete ACTIVE_SHOPIFY_SHOPS[shop];
          },
        });

        if (!response.success) {
          console.log(
            `Failed to register APP_UNINSTALLED webhook: ${response.result}`
          );
        }

        // Redirect to app with shop parameter upon auth
        ctx.redirect(`/?shop=${shop}&host=${host}`);
      },
    })
  );
t-yngt-yng

アクセストークンについて

アクセストークンはShopify側で店舗とトークンを紐付けて保持してくれるため、SDKを経由してトークンを取得をできるので、アプリ側でトークンを管理する必要がない。