Open10

delegate access token (Shopify-Storefront-Private-Token)メモ

さとうあまみさとうあまみ

delegate access token (Shopify-Storefront-Private-Token)を使うと、IPベースのAPI上限とは別の条件でAPIを利用できる?

Usage limitations
If you use a server-side library, the IP address of the request will be your server’s address. To ensure your app is throttled correctly, use a delegate access token and pass it in the Shopify-Storefront-Private-Token header from server contexts.
https://shopify.dev/api/storefront

Authenticated access to the Storefront API enables your app to make requests from private or authenticated contexts like an Oxygen deployment, Hydrogen backend, or other server. With authenticated access, your requests are throttled at the shop level and optionally by a forwarded IP.

https://shopify.dev/api/usage/authentication#getting-started-with-authenticated-access

Use a server to build custom storefronts with authenticated access for the Storefront API API
EFFECTIVE SEPTEMBER 16, 2022
You can now use authenticated access to make Storefront API requests from a server (for example, from a Hydrogen server).
Using authenticated access enables more throughput for your server than using a public token, and enables Shopify's bot protection features to work more effectively.
https://shopify.dev/changelog/use-a-server-to-build-custom-storefronts-with-authenticated-access-for-the-storefront-api

さとうあまみさとうあまみ

通常は Storefront APIは minimum 0.5s per request, 60s per user IP で、1 IPアドレスあたり60秒につき最大120リクエストが上限。
SSRではアクセスのたびにサーバーからAPIにリクエストが飛ぶので、この上限を超過する可能性がある。SSGでもデプロイ時には超過するかも。

https://shopify.dev/api/usage/rate-limits

さとうあまみさとうあまみ

CSRにすれば、アクセスした閲覧者のIPアドレスからリクエストを飛ばせるが、商品ページなどをCSRにするとOGPなどのMETAタグ出力に対応できなくなる(たぶん)

さとうあまみさとうあまみ

delegate access token を使う場合、顧客によるリクエストはShopify-Storefront-Buyer-IPをリクエスト時に同時に投げるのがベストプラクティス。

でもNext.jsでどうやる?たとえばISRだとして、最初のデプロイ時にはShopify-Storefront-Buyer-IPをつけずにリクエストして、デプロイ語のISR時にはShopify-Storefront-Buyer-IPをつけてリクエストする…といった対応は可能なのかが分からない。
きっとHydrogenならうまく自動でやってくれるのかな(適当なことをいう)

Optional IP headerAnchor link to section titled "Optional IP header"
It's best practice to include the Shopify-Storefront-Buyer-IP header if you're using authenticated access for handling buyer requests. There are some cases when the API request isn't on behalf of a buyer, such as during a static site build, where the header isn't needed.
Passing the Shopify-Storefront-Buyer-IP header enables the platform to impose IP-level rate limiting as an added protection against a single user, such as a bot, consuming a high level of capacity.

さとうあまみさとうあまみ

さっそくShopifyストアにログインして、Shopify GraphiQL AppからdelegateAccessTokenCreate mutationを投げてみよう…としたら〜
なんかエラー…
再インストールするか😭

さとうあまみさとうあまみ

expires_inを指定しない場合、親のアクセストークンと同じ期間になる。オフラインアクセスを持っている場合は無効にならない。

If you don't specify an expires_in value, then the token expiry defaults to the same time as its parent access token. If the parent token has offline access, then it won't expire.
https://shopify.dev/apps/auth/oauth/delegate-access-tokens

GraphiQLからmutation打って作成した場合、親のアクセストークンの期限はいつになるのだろう??

基本的に新規にアクセストークンを作成した場合にはオフラインモードがデフォルトなのか。

Offline is the default access mode when none is specified.
The access tokens created with the offline access mode are permanent. They are revoked only when the app is uninstalled from a store.
https://shopify.dev/apps/auth/oauth/access-modes#offline-access

さとうあまみさとうあまみ

とりあえずこんな感じでAPIを叩いたら、有効なトークンがもらえた。
delegateAccessScopeで何が指定できるかの一覧が見当たらなかったのでGraphiQLのエラーメッセージを参考にした。
GraphiQLで「エラーですよ」の波線がでているのは気になる…

mutation delegateAccessTokenCreate($input: DelegateAccessTokenInput!) {
  delegateAccessTokenCreate(input: $input) {
    delegateAccessToken {
      accessToken
    }
    userErrors {
      field
      message
    }
  }
}

{"input": {
  "delegateAccessScope": [
    "read_products",
    "read_content",
    "unauthenticated_read_product_listings",
    "unauthenticated_read_product_tags",
    "unauthenticated_read_content"
  ]
 }
}

さとうあまみさとうあまみ

考えていることメモ:
商品ページ内の情報(特に在庫と価格)はCSRで最新情報を表示
それ以外のページはSSR用トークンを使って長めのISRにして、負荷をおさえつつ、デプロイ手間を省き情報を表示。ISRならOGPも表示できる。