有効期限付きオフラインアクセストークン リフレッシュ失敗からの「復旧経路」ができた
原題: More resilient refreshes for expiring offline access tokens
- OAuth
- Apps
- アクセストークン
- Admin API
- 認証
- セキュリティ
- 仕様変更
- Webhook
図解 : 有効期限付きオフラインアクセストークンのリフレッシュが「復旧可能」になった Developer Changelog / 認証・トークン 有効期限付きオフラインアクセストークン リフレッシュ失敗からの「復旧経路」ができた リフレッシュのレスポンスを取りこぼしても、直前の refresh token が「置換トークンを使い始めるまで」生き残る。60 分の猶予枠に間に合わなかったアプリが、マーチャントの再インストール無しで自力復帰できるようになった。移行作業は不要。 このページの構成 そもそも何が変わったのか(30秒で理解) 図解 : 事故が起きるタイミングと復旧経路 旧挙動 vs 新挙動の比較 3 つの時間軸(置換使用まで/30日/90日) 影響を受けるアプリ/受けないアプリ アプリ側でやること(移行は不要) 技術者が押さえるべき5つのポイント 業務に活かせる3つのユースケース 提案で使える1行サマリ 1 そもそも何が変わったのか 有効期限付きオフラインアクセストークンのリフレッシュで、 直前に使った refresh token が「置換トークンをアプリが使い始めるまで」保持される ようになった。 リフレッシュのレスポンスを失った/保存できなかったアプリが、そこから復旧できる。 マイグレーションは不要 。 これまで : 60 分の砂時計 refresh token を使った後、その同じトークンで再試行できるのは 最大 60 分 。その窓を過ぎると、保存済みの古い refresh token はもう使えなかった。応答を取りこぼしたアプリはそこで詰む。 これから : 「置換を使うまで」有効 保存済みの古い refresh token は、 アプリが置換 refresh token を使い始めるまで 再試行できる。時計ではなく「アプリの状態」が期限になった。 新しい API バージョン・設定変更・opt-in はいずれも 不要 。ロールアウトとして自動的に効く。 ただし「トークンペアをアトミックに保存する」実装責務はこれまで通りアプリ側に残る。 2 図解 : 事故が起きるタイミングと復旧経路 事故の本質は 「Shopify 側はリフレッシュを処理済み、アプリ側は返ってきたペアを未保存」 という食い違い。この隙間はネットワーク・ワーカー・DB のどこでも発生し得るので、実装をいくら丁寧にしてもゼロにはできない。だからプラットフォーム側に復旧経路が用意された。 3 旧挙動 vs 新挙動の比較 項目 これまで これから 旧 refresh token の再試行可否 最大 60 分 使用後、一定時間だけ再試行可 置換を使うまで 時間ではなく状態で判定 応答ロスト時の挙動 窓を過ぎると旧トークンが使用不可 → 復旧手段なし 保存済みの旧トークンで再試行し、新ペアを取り直せる マーチャントの操作 アプリを開き直してもらう必要があった 不要 アプリ側だけで復帰できる 旧トークンが retire されるタイミング 時間経過 アプリが置換 refresh token を 使用した時点 導入に必要な作業 — なし API バージョン更新・設定変更・opt-in 不要 トークン全体の寿命 — 通常の 90 日 を超えて延長されることはない 4 3 つの時間軸を取り違えない 状態 置換を使い始めるまで アプリが置換 refresh token を使った瞬間、直前のトークンは retire される。つまり「復旧経路が閉じるトリガーはアプリ自身の行動」。 上限 30 日 復旧期間は、元の refresh token の初回使用から 30 日まで。放置し続けて無限に古いトークンが生き残るわけではない。 不変 90 日 refresh token 本来の寿命は 90 日のまま。今回の変更でトークンが延命されることはない。 5 影響を受けるアプリ/受けないアプリ 対象 : 有効期限付きオフラインアクセストークンを使うアプリ 自動的に新しい挙動が適用される。新しい API バージョン・設定変更・opt-in はいずれも不要。 対象外 : 有効期限付きオフラインアクセストークンを使っていないアプリ 影響なし。記事中でもそれ以上の言及は無い。 ロールアウトの開始日・完了日、対象ストア範囲、オンラインアクセストークンへの影響は 記載なし 。エラーコードやレスポンス形式の変更点についても記載なし(挙動の変更のみが告知されている)。 6 アプリ側でやること(移行は不要) すでに有効期限付きオフラインアクセストークンを使っているなら、マイグレーションは不要。以下は「引き続き守るべきこと」として明示されている 4 点。 1 ショップ単位で直列化 リフレッシュ操作は shop ごとに serialize する。並行リフレッシュを走らせない。 2 ペアをアトミックに保存 返ってきた access token と refresh token を ひとつのトランザクション で永続化する。 3 常に最新を使う 以降のリフレッシュには 最新の refresh token を使う。古い方を通常運用に混ぜない。 4 あくまで復旧経路 置換トークンを保存済みなのに古いトークンを使い続ける理由にはしない。非常口であって常用ドアではない。 アトミック保存が守れていれば、この変更は「万一のときに効く保険」 として静かに機能する。逆に、access token だけ先に保存して refresh token を後から書くような実装だと、事故時の状態が読みにくくなる。今回の告知は実質「アトミック保存を今一度確認せよ」というメッセージでもある。 7 技術者が押さえるべき5つのポイント 1. 無効化の条件が「時間」から「状態」へ 旧挙動は使用後 60 分の時間窓。新挙動は「置換トークンをアプリが使い始めたら旧トークンを retire」。テストやリトライ設計で 時計を前提にした assumption があるなら見直しどころ。 2. アトミック保存は依然としてアプリの責務 プラットフォーム側が復旧経路を用意しただけで、access token と refresh token をペアで書く実装義務は変わらない。片方だけ書ける経路が残っていると、復旧経路を使う前提の状態管理が崩れる。 3. shop 単位の直列化は前提条件 「ショップごとにリフレッシュを serialize せよ」が明記されている。複数ワーカーが同時にリフレッシュを叩く構成だと、どのトークンが最新かの判定が壊れる。分散ロックやキューでの排他は引き続き必要。 4. 復旧期間には上限がある(30 日 / 90 日) 復旧できるのは元の refresh token の初回使用から 30 日以内。通常の 90 日寿命も延びない。「壊れたまま数か月放置したストア」は依然として救えないので、リフレッシュ失敗の検知・アラートは必要。 5. 導入コストはゼロ、ただし「棚卸しの機会」として使える 新 API バージョン・設定変更・opt-in がいずれも不要なので、何もしなくても恩恵は受けられる。一方で告知の「continue to」リストは、既存実装の監査項目そのもの( shop 単位の直列化 / ペアのアトミック保存 / 最新トークン使用 / 復旧経路の常用禁止 )。この 4 点を満たしているかのチェックは今やる価値がある。 8 業務に活かせる3つのユースケース USE CASE 1 公開アプリの「認証切れ問い合わせ」を減らす 課題 リフレッシュの応答を取りこぼしたテナントで API 呼び出しが失敗し続け、マーチャントから「同期が止まった」と問い合わせが来る。復旧にはアプリを開き直してもらう案内が必要だった。 打ち手 リフレッシュ失敗を検知したら、保存済みの refresh token で再試行するリカバリジョブを回す(今回の変更で、置換を使い始めていなければ通る)。合わせて失敗テナントの検知アラートを整備。 効果 マーチャント操作を伴う復旧案内の削減。サポート対応工数と、認証切れ起因の解約リスクの低減。 技術メモ 復旧できるのは元トークンの初回使用から 30 日以内。それを超えたテナントは救えないので、検知は「日次」ではなく早いサイクルで。 USE CASE 2 マルチワーカー構成のトークン更新を監査する 課題 バックグラウンドジョブが複数ワーカーで並列に走り、同じショップのリフレッシュが同時に発火し得る。どのトークンが最新かの判定が状況次第で揺れる。 打ち手 告知の「continue to」4 項目を監査チェックリスト化 : ① shop 単位でリフレッシュを直列化しているか ② access/refresh をアトミックに保存しているか ③ 常に最新トークンを使っているか ④ 古いトークンを常用していないか。 効果 今回の復旧経路が実際に効く状態を担保できる。トークン起因の断続的な 401 の再発防止。 技術メモ 置換トークンを使った時点で旧トークンは retire される。復旧経路を残したいなら「新トークンを保存した後、実際に使い始めるまで」の間に旧トークンを捨てない設計が有利。 USE CASE 3 障害対応ランブックに「トークン復旧手順」を足す 課題 DB 書き込み失敗やワーカー障害の事後対応で、トークンが壊れたテナントの復旧手段が「マーチャントに再訪してもらう」しかなく、手順として書きづらかった。 打ち手 ランブックに「障害時間帯にリフレッシュを実行したショップを洗い出し、保存済み refresh token で再試行する」節を追加。復旧可能なウィンドウ(初回使用から 30 日、かつ置換未使用)も明記する。 効果 障害の事後処理が定型化し、対応時間とマーチャント接触の回数が減る。 技術メモ この経路はあくまで復旧用。置換トークンを保存済みのショップに対して古いトークンを使い回す運用にしてはいけない、と明示されている。 9 提案で使える1行サマリ 「リフレッシュの応答を取りこぼしても、直前の refresh token が 置換トークンを使い始めるまで 生き残るようになった。 移行作業ゼロ・API バージョン更新不要 で、マーチャントの再操作なしに認証切れから自力復帰できる。 やることは 1 つ : トークンペアのアトミック保存とショップ単位の直列化が守れているかを確認するだけ。」 source : shopify.dev / changelog / more-resilient-refreshes-for-expiring-offline-access-tokens published 2026-08-28 / generated 2026-09-09