Shopify会員限定ページの作り方と予約フォーム埋め込みの注意点【アプリ不要・Liquid数行】
Shopifyには標準で「特定のページを会員限定にする」機能がありませんが、アプリを追加しなくても、テーマにLiquidのコードを数行入れるだけで実現できます。この記事では、外部の予約フォームを埋め込んだページを会員限定にした実例をもとに、管理画面のどこを操作するのかという具体的な手順から解説します。
あわせて、実際にやってみて分かった注意点も紹介します。特に「Shopifyのページを会員限定にしても、埋め込んだフォーム自体のURLは誰でも開ける」という点は見落としやすく、対策を1つ間違えると会員に不要な手間を強いることになります。手順と注意点をセットで押さえてください。
Shopifyで会員限定ページを作る手順(アプリ不要)
作業は大きく4ステップです。OS 2.0系テーマ(Dawnなど)であれば、テーマのコードファイルを直接編集する必要はなく、テーマエディタの操作とコードのコピー&ペーストだけで完結します。
手順1:外部フォームをページに埋め込む
まず、会員限定にしたいコンテンツを通常のページとして作ります。今回は外部の予約管理サービス(セレクトタイプ)の予約フォームを埋め込みました。Shopify管理画面の「オンラインストア」→「ページ」でページを作成し、本文エディタを<>(HTML表示)に切り替えて、予約サービス側で発行されたiframeの埋め込みコードを貼り付けます。
このとき、iframeのwidth属性は「100%」に書き換えておくのがおすすめです。発行されたコードのままだと幅が固定値になっていることが多く、100%にしておけばスマートフォンでもテーマの幅に合わせて収まります。高さは固定値なので、実際に表示してみてフォームが切れるようなら数値を増やして調整してください。
手順2:会員限定用のページテンプレートを作る
次に、「ログインしていない人にはページ本文を見せない」ためのテンプレートを用意します。「オンラインストア」→「テーマ」→「カスタマイズ」でテーマエディタを開き、画面上部のテンプレート切り替えメニューから「ページ」→「テンプレートを作成」を選択。名前はmembersなど分かりやすいものを付け、デフォルトページを基に作成します。
手順3:ログイン判定のコードを入れる
作成したテンプレートの編集画面で、既存の「ページ」セクションを削除(または非表示に)し、代わりに「セクションを追加」→「カスタムLiquid」を選んで、次のコードを貼り付けて保存します。
{% if customer %}
{{ page.content }}
{% else %}
<p>このページは会員限定です。</p>
<p><a href="/account/login?return_url={{ request.path | url_encode }}">ログインはこちら</a></p>
{% endif %}
コードの意味はシンプルです。判定に使っているcustomerオブジェクト(Shopify公式ドキュメント)は、ログイン中の顧客情報が入る変数で、非ログイン時は空になります。そのため「ログインしていればページ本文(=手順1で貼ったiframe)を表示、していなければログイン案内を表示」という出し分けがこの分岐だけで完結します。非ログイン時はフォームのHTML自体が出力されないため、ソースコードを見られてもフォームのURLは漏れません。
もう1つのポイントはログインリンクに付けたreturn_urlです。これを付けておくと、ログイン完了後に自動でこの予約ページへ戻ってきます。付け忘れるとログイン後にアカウントページへ飛んでしまい、訪問者が予約ページへ戻る道を見失います。
手順4:ページにテンプレートを適用して動作確認する
「オンラインストア」→「ページ」で手順1のページを開き、テーマテンプレートの欄で作成したmembersテンプレートを選択して保存します。これで設定は完了です。
動作確認は、シークレットウィンドウ(未ログイン状態)でページを開き、次の2点をチェックしてください。①フォームが表示されず、ログイン案内だけが出ること。②「ログインはこちら」からログインすると、予約ページに自動で戻ってくること。なお、Shopifyのカスタマーアカウントには従来型(メールアドレス+パスワード)と新型(メールに届くコードでログイン)の2方式があり、新型ではログイン処理がShopify側の外部ドメインで行われるため、ログイン後の戻り先の挙動が変わることがあります。どちらの方式でも、この一連の動線テストは必ず行ってください。
Liquidとアプリ、どちらで作るべきか
会員限定ページの実現方法には、上記のLiquid方式のほかに、Locksmithのようなアクセス制限アプリを導入する方法もあります。判断の目安を表にまとめます。
| 観点 | Liquidで制御 | アクセス制限アプリ(Locksmith等) |
|---|---|---|
| 費用 | 無料 | 月額費用が発生 |
| 実装 | テーマにコードを数行追加 | 管理画面から設定(コード不要) |
| 条件の柔軟性 | ログイン有無などシンプルな条件向き | 顧客タグ別の出し分けなど複雑な条件に対応 |
| 向いているケース | 対象ページが少なく条件が単純 | 対象ページが多い、非エンジニアが日常的に設定を変える |
今回の案件でLiquid方式を選んだ理由は単純で、必要なコードが数行だからです。数行で実現できる機能にアプリを導入するメリットはありません。アプリには月額費用だけでなく、サイトがそのアプリに依存し続けるという運用上のコストも発生します。逆に、「特定の顧客タグを持つ会員だけに見せたい」「制限対象のページが多数あり、コードを触らずに管理したい」といった条件が出てきたときがアプリの出番です。
注意点:埋め込んだフォームの直URLは誰でも開ける
ここからが、実際にやってみて分かった注意点です。手順どおりに設定すればShopify側の会員限定ページは完成しますが、この時点ではまだ守れていない場所が残っています。予約フォーム本体、つまり外部サービス側の公開URLです。
iframeによる埋め込みは、別の場所にあるページを窓越しに見せている仕組みです。Shopifyのページを会員限定にしても、予約サービス側のフォームURL(select-type.com上の直URL)はインターネット上に公開されたままなので、そのURLを知っている人はShopifyのログインを一切経由せずに、直接フォームを開いて予約できてしまいます。
目の前の「会員限定ページ」が正しく動いていると、これで守れたと考えてしまいがちですが、埋め込み型の外部サービスを使う場合は、Shopify側と外部サービス側の両方に対策が必要です。
フォームにパスワードをかけると、会員が二重ログインになる
では外部サービス側をどう守るか。最初に試したのは、予約サービスの機能でフォームにパスワード認証をかける方法です。パスワードを知らない人はフォームの閲覧も予約もできなくなるため、直URLからのアクセスは確実に塞げます。
ところが、実際に設定してみると問題が起きました。パスワード認証はフォーム自体にかかるため、iframe経由のアクセスにも同じ認証画面が表示されるのです。つまり、Shopifyにログインした会員が予約ページを開くと、そこにさらにパスワード入力画面が現れます。外部サービス側から見れば直URLもiframeも同じアクセスなので、「埋め込み経由だけ認証を免除する」という設定は存在しません。
会員の立場で考えると、ログインした直後にもう一度別の認証を求められる、理由の分からない画面です。しかも、そのパスワードを会員に伝える自然な手段がありません。ページ内にパスワードを書いておく回避策もありますが、それではパスワードをかけた意味が薄れる上に、変更のたびに記載を更新し続ける手間だけが残ります。設定としては作れても、会員が毎回スムーズに予約を完了できて、管理側も無理なく維持できる形になっていなければ、その対策は実際には機能しません。パスワード認証は今回のケースではその条件を満たせず、採用を見送りました。
採用した対策:直URLを検索結果と導線から隠す
最終的に採用したのは、パスワード認証を外した上での次の2つの設定です。
- 予約サービス側で「検索エンジンを拒否する」設定を入れる:フォームの直URLがGoogleなどの検索結果に表示されなくなります。
- 直URLへのリンクをShopifyの会員限定ページ以外に一切置かない:予約サービスのホームページ機能やSNSなど、フォームURLへの導線をすべて閉じます。
この2つで、フォームURLを知る手段は「会員限定ページを開く」だけになります。フォームURLの識別子は長いランダムな文字列なので、推測で当てることは事実上できません。つまり、URLを知り得るのはログイン済みの会員だけです。
残るリスクは「会員が直URLを外部の人に教えてしまう」ことですが、これはパスワード方式でも同じでした。パスワードも同じように教えられてしまうからです。防げるリスクの範囲が実質的に変わらないのであれば、会員に毎回の入力を強いない方式を選ぶべきだと判断しました。対策を比較するときは、見た目の厳重さではなく「その対策で実際に何が防げて、何が防げないのか」を並べてみることをおすすめします。
「どの会員が申し込んだか」はメールアドレスの事後照合で分かる
今回の案件では、会員限定化とあわせて「どの会員が申し込んだのかを把握したい」という要望もありました。これを「非会員の予約を検知するためのチェック」と捉えると、予約を承認制にして会員リストと突き合わせるような重い仕組みが必要に見えてきます。しかしクライアントの目的はマーケティングでした。どの会員がどのイベントに申し込んだかを把握し、次の施策に活かしたい。それなら、リアルタイムのシステム連携は不要で、予約時のメールアドレスと会員データを後から照合すれば十分です。
| 要望 | 中身 | 必要な仕組み |
|---|---|---|
| 非会員に予約させたくない | アクセスの制限 | ログイン判定+直URLの検索回避・導線遮断 |
| どの会員が申し込んだか知りたい | データの活用 | メールアドレスの事後照合(システム連携は不要) |
「会員限定にしたい」という一言の中に、性質の違う2つの要望が入っていたわけです。分けて考えると、片方はログイン判定とURL管理という軽い仕組みで足り、もう片方は手作業の照合で足りることが分かります。
なお事後照合には、会員がShopifyの登録アドレスと違うメールアドレスで予約してしまうと突き合わせられない、という実務上の落とし穴があります。フォームの近くに「会員登録時のメールアドレスをご入力ください」と一言添えておくだけで防げるので、この方式を採る場合はセットで入れておくことをおすすめします。ちなみに、Shopifyの標準機能に潜む思わぬ落とし穴という意味では、顧客統合でポイントが消える問題を整理した記事もあわせて参考になるはずです。
今回の案件の背景:「一体型のアプリはないか」という相談から
最後に、この構成にたどり着いた経緯を紹介します。発端はクライアントからの「予約管理機能と会員認証機能が一体になったShopifyアプリはないか」というご相談でした。会員向けイベントの予約受付を会員限定にしたい、という意図です。
この条件に合致するアプリは、おそらく存在しないか、あっても選択肢が極端に狭くなります。そこで、要望を「予約機能」と「会員限定化」に分け、予約機能は使い慣れた外部の予約管理サービス、会員限定化はShopify標準のログイン判定、という既存の部品の組み合わせで応えました。探していた形の製品が見つからなくても、要望を分解すれば既存の仕組みで実現できることは珍しくありません。同じような探し物をしている方は、諦める前に一度、要望を機能単位に分けてみてください。
外部サービスを埋め込む前に確認したい3つのポイント
- 外部サービス側のアクセス制限機能を先に調べる:埋め込み先のページを守っても、埋め込み元のURLは誰でも開けます。外部サービス側にどんな制限機能があり、それがiframe経由のアクセスにどう作用するのかは、実装前に確認しておくべき情報です。
- 認証を重ねたときの画面遷移を先に描く:個々の設定が正しくても、組み合わせた結果「ログインしたのにまた認証」のような理由の分からない画面が生まれることがあります。設定を入れる前に、訪問者が最初のアクセスから予約完了までにどの画面を通るかを一度なぞってみてください。
- 要望を分解し、それぞれに必要な仕組みの重さを見極める:「会員限定にしたい」という一言に、アクセス制限の話とデータ活用の話が同居していることは珍しくありません。分ければ、コードで対応すべき部分と、運用の工夫で足りる部分が見えてきます。
なお、外部サービスがそもそも攻撃を受けた場合に自社サイトがどんな影響を受けるかは、読み込み方式によってリスクの濃淡が変わります。こちらは外部サービスが攻撃されたら自社サイトはどうなる?4つの型で整理で詳しく解説していますので、あわせてご覧ください。
ENVY DESIGNでは、Webサイトの制作だけでなく、公開後の保守・運用サポートの中で外部サービスの導入やアクセス制御の設計もお手伝いしています。「この埋め込み、本当に守れているのか」が気になった方は、お問い合わせよりお気軽にご相談ください。
Shopifyの会員限定ページに関するよくある質問
Shopifyには標準で特定のページを会員限定にする機能はありますか?
ありません。テーマのLiquidでcustomerオブジェクトを判定して出し分けるか、Locksmithなどのアクセス制限アプリを導入するかの2択になります。ログイン有無だけのシンプルな条件ならLiquid数行で足り、顧客タグ別の出し分けなど複雑な条件が必要な場合はアプリが向いています。
iframeで埋め込んだ外部フォームは、埋め込み先のページを会員限定にすれば守られますか?
守られません。iframeは別の場所にあるページを窓越しに見せているだけなので、外部サービス側のフォームURLは公開されたままです。直URLを知っている人は埋め込み先のログインを経由せずアクセスできるため、外部サービス側のアクセス制限や検索回避の設定とあわせて対策する必要があります。
外部フォーム側にパスワード認証をかければ解決しますか?
直URLからのアクセスは塞げますが、認証はフォーム自体にかかるため、iframe経由のアクセスにも同じ認証画面が表示されます。ログイン済みの会員にもう一度認証を求める画面遷移になり、パスワードを会員に届ける手段の問題も残るため、導入前に会員側・管理側それぞれの手間を確認することをおすすめします。
予約者が本当に会員かどうかは、どうやって確認すればよいですか?
目的によって必要な仕組みの重さが変わります。マーケティング目的で「どの会員が申し込んだか」を知りたいだけなら、予約時のメールアドレスと会員データの事後照合で十分です。その場合は、フォーム付近に「会員登録時のメールアドレスをご入力ください」という案内を添えて、照合できないケースを減らしておくとよいでしょう。