Forest Book
Shopifyで会員限定販売の「認証漏れ」は完全には塞げない ― フロント制御の限界と注文Webhookによる事後検証

Shopifyで会員限定販売の「認証漏れ」は完全には塞げない ― フロント制御の限界と注文Webhookによる事後検証

2026年8月2日

会員だけに購入を許可したいECは多い。福利厚生の社販、限定会員向け販売、資格保有者だけが買える商材など、要件はさまざまだが、共通するのは「非会員にチェックアウトを完了させたくない」という一点だ。ところがShopifyでこれを実装しようとすると、フロントエンドの制御だけでは購入を止めきれない経路が必ず残る。当社ではこうした案件を「完全防止は原理的に難しい」という前提から設計している。この記事では、なぜフロント制御だけでは不十分なのか、そして注文作成Webhookを使った事後検証という現実解をどう組み立てるかを整理する。会員限定販売を検討しているEC事業者と、それを受託する技術者に向けた内容だ。

フロントエンドの認証チェックは「善意の利用者」しか止められない

一番手軽な実装は、商品ページやカートページで認証状態を確認し、未ログインなら購入ボタンを無効化する方式だ。ログイン情報をクッキーやセッションに保持し、複数商品を買うたびに再認証が走らないよう制御する。カート追加時とチェックアウト遷移時にチェックを挟めば、通常のブラウザ操作で買い物をする限りは会員以外を弾ける。

問題は、この制御がすべて「画面の上」で完結している点にある。Shopifyのチェックアウトは、商品バリアントのIDさえ分かれば画面を経由せずに開始できる。具体的には、開発者ツールから直接カート追加やチェックアウト開始のリクエストを投げる経路、/cart/{variant}:{qty} 形式のパーマリンクからチェックアウトに直行する経路、チェックアウトURLに直接遷移する経路、そしてShop Payのような外部の高速決済からストアフロントの制御を飛ばして注文が成立する経路がある。これらはいずれもフロントのボタン制御を無視するため、「画面を操作しないユーザー」には無力だ。

ここで重要なのは、正直に見積もりへ書くことだ。当社では簡易構築のパターンを提案する際、「フロントエンド中心の制御となるため、開発者ツールによる直接リクエストやパーマリンク経由のチェックアウトまでは防止できません」と明記している。防げないものを防げるかのように書くと、リリース後に「認証漏れが起きた」というクレームに直結する。技術的な限界は、契約前に共有しておくのが誠実であり、結果的にトラブルを減らす。

サーバーサイド検証を足しても「完全」にはならない

一段踏み込んだ構築では、カスタムアプリのサーバーサイドで認証状態を検証し、チェックアウト時にサーバー側で制御をかける。これで直接リクエストやパーマリンクといった回避手段の多くは塞げる。ただし当社では、この段階の構築を「具体的な実装をあらかじめ確定しているもの」としては提案していない。回避経路はストアの構成やアプリの組み合わせによって変わり、Shopifyの仕様上どうしても完全には塞げない経路も残るからだ。

そのため設計思想としては、「回避手段を要件定義の中で一つずつ洗い出し、リスクごとに対策を設計・実装していく」という段階的なアプローチを取る。最初から「絶対に漏れない」と約束するのではなく、既知のリスクを潰しながら、残存リスクは運用でカバーする、という組み立て方だ。これはコストの見通しにも効く。すべての経路を実装前に列挙して固定価格で請け負うより、精査の結果を都度相談しながら対策範囲を決めるほうが、双方にとって無理がない。

現実解は「入口で止める」ではなく「出口で検知する」

フロントもサーバーも突破される可能性が残るなら、発想を切り替える。入口(チェックアウト)で完璧に止めることに固執せず、出口(注文作成後)で検知する仕組みを併走させるのだ。

具体的には、注文作成Webhookを受けて、その注文が認証済み会員によるものかを事後検証する。認証プロセスを経ていない疑いのある注文には、Shopify管理画面上で識別できるようタグでフラグを立てる。店舗側はそのフラグを見て、該当注文のキャンセルや返金を判断する。チェックアウトを突破されても、注文が成立した直後に「これは怪しい」と分かる状態を作っておけば、被害は水際で止められる。

この方式を採るとき、当社が必ず設計に含める論点が二つある。ひとつは誤検知の扱いだ。事後検証は完璧ではなく、正当な会員の注文を「疑わしい」と判定してしまうこともある。だから疑義注文を自動キャンセルにするかどうかは、要件定義の中で慎重に決める。誤ってキャンセルすれば正規の顧客を怒らせるので、初期は自動化せず、フラグ付けにとどめて人が最終判断する運用を推奨することが多い。もうひとつは通知だ。フラグを立てるだけでは店舗が気づかないので、検知と同時に管理者へメール等で通知する仕組みを組む。ただし通知機能は見積もりのスコープに含まれているとは限らないため、別途の追加実装として切り分けておく。

「誰が会員か」を数える鍵は、Shopifyの顧客IDではないことが多い

会員限定販売には、「一人あたりの購入上限」を設けたいという要件がしばしば付いてくる。生涯で何個まで、といった制限だ。これを実装するとき、素朴にShopifyの顧客IDをキーにすると設計を誤りやすい。

会員限定販売の多くは、Shopifyの外側に会員基盤を持っている。人事システムや会員管理サービス、資格認定のデータベースなどだ。この場合、上限管理のキーはShopifyの顧客IDではなく、外部会員基盤の会員番号にするのが正しい。会員番号をキーにして、注文ID・対象商品・購入数量・累計購入数をカスタムアプリ側のデータベース(当社ではDynamoDBを使うことが多い)に保存し、注文作成Webhookを起点に累計を更新する。購入時には会員番号単位で上限をチェックする。こうしておけば、会員がShopifyアカウントを作り直しても、退会・再入会しても、会員基盤と一貫した個数管理が保てる。Shopifyの顧客IDを鍵にしてしまうと、アカウントを分ければ上限を回避できてしまい、制限が意味をなさない。

まとめ

会員限定販売の「認証漏れ対策」は、「完全に防ぐ機能」ではなく「防ぎきれない前提でリスクを管理する設計」として捉えるのが正しい。フロントエンドの制御は通常操作のユーザーしか止められず、サーバーサイド検証を足しても完全にはならない。だからこそ、入口での防止と、注文作成Webhookによる出口での事後検証・タグ付けを組み合わせ、誤検知と通知の運用まで含めて初めて実務に耐える。上限管理のような付随要件では、数えるキーを外部会員基盤の会員番号に置くことも忘れてはならない。当社では、この「防げないものは正直に伝え、出口で拾う」という設計方針を、会員限定販売の標準的な考え方として提案している。契約前に限界を共有しておくことが、リリース後の信頼を守る一番の近道だからだ。