アプリ側での顧客管理機能ログイン判定方法

質問

onlineshop側にコンテンツを出すアプリの開発をしたいと思っています。
表示するコンテンツはログインしているユーザー毎に変えたいと思っています。

その場合、アプリは、onlineshopにアクセスしたユーザーのログイン情報(ログインしてるか、誰としてログインしているか)はどのように取得するのでしょうか?

例えば、ログインしている人の購入履歴にもとづき、おすすめ商品情報を出すアプリを作るとします。
すでに、アプリのDBには購入履歴にもとづいたおすすめする商品情報が保存されている状態です。

onlineshopにアクセスしたとき、アプリ側で用意した、おすすめする商品情報を返すAPIにアクセスするのですが、アクセスした人が誰なのかアプリ側では判別付きません。

検討したこと①

APIのパラメーターにliquidテンプレートで出力した {{customer.id}} とかを付与してもいいのですが、その場合、適当なcostomer idを指定してAPIを投げると他の人のおすすめ情報が無関係にから取り出せてしまいます。その情報に価値があるかどうかは一旦ここでは議論しませんが、やはりログインしている本人のデータしか返さないようにしたいです。

検討したこと②

webhookを利用して、ユーザーが作られた際にアプリ側のDBにもユーザー情報を保存。
アプリで用意した、おすすめ情報のAPIを呼び出す際に、costomer id と email address をパラメーターに付与して投げる。
この場合、前述のケースと比べて、costomer idとemail addressのパターンを無関係の人が推測するのは難しいので、まだ良いのですが、、、よりスマートな方法があれば知りたいと思っています。

以上のように、色々手を尽くせばそれっぽいことができそうではあるのですが、アプリ側がonlineshopにアクセスしに来た人のログイン情報を判別する方法ってそんあ周りくどいことをしないとできないことなのでしょうか??

なにか方法があれば、教えていただきたいです。

2 Likes

通城は、おっしゃる通り、Liquidのcustomer.idを使うのが定石かと思います。

その際に、他のIDのデータが引けてしまう問題ですが、アプリ開発をする場合は、App proxy という仕組みを使って、フロントのデータをアプリのバックエンドに渡すことができます。
https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extension

これには、改竄防止のハッシュキーによるバリデーションがついているため、例えばApp proxyに custome_id=123 とコールされているところを、customer_id=234 としてGETした場合、

値が異なるのでハッシュキーもことなり、ハッシュキーの算出に必要なキーは、Shopifyとアプリしか知らないため、実質パラメータの改ざんはできなくなります。

アプリの開発については、日本語で以下にまとめてありますので、一度ご確認ください。

https://www.shopify.jp/blog/partner-shopify-app-development

上記ブログを基にした解説動画もあります。

あとは、公式の方法ではないですが、以下のようなアプローチをされている方もいるようです。
https://community.shopify.com/c/Shopify-APIs-SDKs/Current-best-way-to-get-logged-in-customer-id/td-p/482773

1 Like

返信ありがとうございます!

上記、App proxyも検討してみたのですが、

  • cookie関連のheaderはshopifyによって削除されてします
  • パラメーターの改ざん防止機能は、shopify —> proxied app 間の検証で、user —> shopify —> proxied app の検証には利用できない

と思い採用しませんでした :sweat_smile:

パラメーター改ざん防止機能について補足すると、例えば、アプリ側にある example.com/api/user?cid=xxx のパスがapp proxyによりshopify側から転送される予定の場合、以下2通りのアクセスの可能性があると思っています。

App proxyのパラメーター改ざん防止機能は上記ケースのうち、後者の検証のためにだと認識しています。
ご説明頂いた通り、パラメーターとハッシュキーの照合により、リクエストがshopifyから転送されたものかどうか、検証できます。

しかし、前者のケースはやはり、cidがログインしているユーザーのものである検証ができません。
example.myshopify.com/app/my-proxied/user?cid=xx のリクエストで、cidを適当に指定してリクエストすると、結局shopifyを経由してアプリ側に転送されるので、shopifyを経由していることの検証はできますが、ログインユーザーである検証ができません。認識違っていたら、コメントもらえると嬉しいです。 ?

あとは、公式の方法ではないですが、以下のようなアプローチをされている方もいるようです。> https://community.shopify.com/c/Shopify-APIs-SDKs/Current-best-way-to-get-logged-in-customer-id/td-p/482773

上記も事前に、確認していました!
いくつかのテーマではcustomer idはliquidテンプレートからjavascriptからもあつかれるようにセットされているようで、しかしセットされている場所(JavasScript変数名)がテーマ毎に違うので、皆さん頑張って解析してJSからcidを利用していると認識しています。出処はliquidテンプレートで、結局customer idなので、依然として、ログインしているユーザーであることの確証 が得られないので参考にはしていませんでした :sweat_smile:

1 Like

確かに、App proxy内でのIDの保証はできないですね。。

ログインしている人のデータは、Cookieやローカルストレージに入っているので、そこから参照して、App proxyに渡す方法もありますが、根本的にアプリサーバー側で、これが本当にログイン(セッション上)のIDかどうかなのかの検証にはならないですね。

自分の方で、もう少し適切な方法がないか探してみます。

以下のアプローチを見つけたので、共有します。

http://gavinballard.com/securing-customer-pages-shopify-app-proxy/

詳細はみてないですが、IDだけではなくて、他にLiquidから取れるデータをパラメータで渡して、サーバー側ではIDで取得したCustomerデータと渡ってきたデータを比較して、ログインしているひとか判断する方法です。

原始的ですけど、これだと、たまたま他の人のデータを参照してしまうことは防げるかと思います。

3 Likes

返信ありがとうございました!記事を読んでみたところ、costomer id 以外との組み合わせで costomer id の推測を軽減させるアプローチのようですね。
事前に共有させて頂いた、検討したこと② とアプローチは同じようです。

現実的な方法はとりあえずこの辺に落ち着くのですかね。。。 :sweat_smile:

調査、返信ありがとうございました!

すでに解決済となっていますが、弊社がリリースしている ソーシャルPLUS アプリで実施している手法を遅ればせながら記事にして公開いたしましたので参考にしていただけると幸いです。

junichiokamura さんが紹介されていた記事 Securing customer pages with a Shopify app proxy よりもセキュアに実装する手法についても掲載しております。

ストアにログイン中のカスタマーからのリクエストを Shopify App でセキュアに判別する方法

1 Like

今更ですが、いつかの更新で、 app proxies のパラメーターに logged_in_customer_id が追加され、ログイン中の user id がわかるようになっていました。

https://shopify.dev/apps/online-store/app-proxies

2 Likes

情報共有ありがとうございます!

ScriptTagからAppProxyへXMLHttpRequest()を送付することで、logged_in_customer_idが付与され、customer_idが取得できました。