フューチャー技術ブログ

Auth0アカウントでShopifyにSSOする

サムネイル.png

はじめに

はじめまして。2021年4月新卒入社、TIGの武田です。入社して早半年、最近開発の面白さに気付かされ、巷のエンジニアあるあるにも3割くらい共感できるようになりました。

私が参画した案件で、Auth0に登録されているエンドユーザ向けのアカウントを用いてShopifyにSSOする検証を行ったので、今回はその方法をご紹介します。

SSOとは?

一度のユーザ認証を行うと、以後そのユーザ認証に紐づけられているサービスを、追加の認証なしで利用できる機能です。
これにより、ユーザはパスワードの記憶や管理の負担が減り、システム管理者はセキュリティ上の弱点を削減することができます。

Auth0とは?

Auth0導入編をご参照ください。他にもAuth0関連の記事があります。

Shopifyとは?

本格的なネットショップが開設できるECプラットフォームで、世界NO. 1のシェアを誇っています。詳しくは公式サイトをご覧ください。

前提条件

実環境でSSO機能を利用するためには、ShopifyPlusのサブスクリプションが必要となります。また、Shopifyには無料の開発者向けの環境が用意されており、様々な機能をテストすることができます。今回は、開発者用ストアを使ってSSOを実装していきます。

Auth0のアカウントも必要になります。こちらも無料のものが提供されているので、今回はそちらを使います。

サンプル実装

マルチパスを利用して、Auth0アカウントでShopifyにSSOできるよう実装していきます。

目次

1. Shopifyアカウントでマルチパスを有効にする

2. Auth0アプリケーションを作成し、URIを設定する

3. Auth0ルールを追加して、マルチパストークンを作成する

4. ShopifyテーマにAuth0リンクを設定する

Shopifyアカウントでマルチパスを有効にする

Shopifyストアにログインし、 設定に移動して チェックアウトウィンドウをクリックします。顧客アカウントを、任意または必須に設定することで、ストアでマルチパスを有効にできます。

技術ブログ①.png

このシークレットキーはマルチパスリクエストが正当であることを確認するための暗号を作成するために使用されます。シークレットキーを再発行したい場合、マルチパスを無効にしてから再度有効にすることで、新たなシークレットキーが生成され、以前のものは無効化されます。(上記画像のシークレットキーは既に無効化済みです。)

Auth0アプリケーションを作成し、URIを設定する

Auth0ダッシュボード内でApplicationsに移動し、Create Applicationをクリックして適当な名前を付け(「Shopify Store」など)、Regular Web Applicationsを選択し、CREATEします。
技術ブログ②.png

Settingsに移動します。

Application URIsを以下のように設定します。
{shopify-domain}は自身のストアのドメインに置き換える必要があります。(例:sample-store.myshopify.com)

  • Application Login URI:https://{shopify-domain}/account/login
  • Allowed Callback URLs:https://{shopify-domain}/account
  • Allowed Logout URLs:https://{shopify-domain}/account/logout技術ブログ④.png

Advanced Settingsセクションを展開し、Application Metadataに次の2つのKeyとValueのペアを追加します。

  • Key:shopify_domain ; Value:{shopify-domain}
  • Key:shopify_multipass_secret ; Value:{multipass-secret}技術ブログ③.png

Auth0ルールを追加して、マルチパストークンを作成する

Auth0ダッシュボードのAuth PipelineRulesに移動して、Createを選択、templateはEmpty ruleを選択します。
わかりやすい名前(「ShopifyMultipass」など)を付け、次のコードを貼り付けます。

function (user, context, callback) {
if (context.clientMetadata && context.clientMetadata.shopify_domain && context.clientMetadata.shopify_multipass_secret)
{
const RULE_NAME = 'shopify-multipasstoken';
const CLIENTNAME = context.clientName;
console.log(`${RULE_NAME} started by ${CLIENTNAME}`);

const now = (new Date()).toISOString();
let shopifyToken = {
email: user.email,
created_at: now,
identifier: user.user_id,
remote_ip: context.request.ip
};
if (context.request && context.request.query && context.request.query.return_to){
shopifyToken.return_to = context.request.query.return_to;
}

const hash = crypto.createHash("sha256").update(context.clientMetadata.shopify_multipass_secret).digest();
const encryptionKey = hash.slice(0, 16);
const signingKey = hash.slice(16, 32);

const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-128-cbc', encryptionKey, iv);
const cipherText = Buffer.concat([iv, cipher.update(JSON.stringify(shopifyToken), 'utf8'), cipher.final()]);

const signed = crypto.createHmac("SHA256", signingKey).update(cipherText).digest();

const token = Buffer.concat([cipherText, signed]).toString('base64');
const urlToken = token.replace(/\+/g, '-').replace(/\//g, '_');

context.redirect = {
url: `https://${context.clientMetadata.shopify_domain}/account/login/multipass/${urlToken}`
};
}
return callback(null, user, context);
}
  • 2行目:Auth0アプリケーションがshopify_domainとshopify_multipass_seceretのメタデータを保持しているときのみこのルールが実行されるようにします。
  • 4〜6行目:ルールが実行されていることを確認するためのロギングです。
  • 8-14行目:Shopifyには最低でもemailとcreated_atのデータが必要です。追加情報として、identifier(複数のAuth0アカウントが同じemailアドレスを持っている場合)、remote_ip(最初にログインリクエストを送信したコンピューターでのみこのマルチパスリクエストを使用できるようにする場合)を入れることができます。
  • 15〜17行目:return_toクエリ文字列に値がある場合は、これをShopifyトークンに追加します。
  • 19〜30行目:ここで実際に暗号化を行っています。GitHubのリポジトリを参照。
  • 32〜34行目:これにより、認証されたユーザの宛先が設定されます。
    このルールが実行されると、ユーザはShopifyストアにリダイレクトされます。このルールの後にAuth0ルールがある場合、それらは完全にスキップされてしまうため、お気をつけください。
技術ブログ⑤.png

ShopifyテーマにAuth0リンクを設定する

Shopifyテーマを編集してログイン/ログアウトするためのリンクを追加していきます。
Shopifyストアの現在のテーマのコードを編集をクリックします。
技術ブログ⑥.png

まずは、ログインページを編集してログインリンクを追加します。Templatesフォルダ内のcustomers/login.liquidファイルを開き、リンクを追加するのに適した場所を見つけます。今回は、アカウント作成リンクの下に以下のリンクを配置します。

<a href="{{ settings.auth0_login_url }}">Log in with Auth0</a>
技術ブログ⑦.png

次に、アカウントページを編集してログアウトリンクをAuth0のログアウトリンクに置き換えます。Templatesフォルダ内のcustomers/account.liquidファイルを開き、ログアウトリンクを以下のリンクに置き換えます。テーマ内の他の場所にもログアウトリンクがある場合は、それも同様に置き換える必要があります。

<a href="{{ settings.auth0_logout_url }}">log_out</a>
技術ブログ⑧.png

続いて、ユーザがログインURLとログアウトURLを貼り付けることができるようにテーマ設定を追加します。Configフォルダ内のsettings_schema.jsonファイルを開き、以下のスニペットを配列の最後に貼り付けます。

ここでは、「Auth0 Config」という新しい設定セクションを作成し、ログインURLとログアウトURLを入力できるようにしています。idプロパティは、上記のリンクで使用したプロパティの名前と一致させる必要があります。

{
"name": "Auth0 Config",
"settings": [
{
"type": "text",
"id": "auth0_login_url",
"label": "Auth0 Login Url",
"info": "The full Auth0 URL to redirect the customer to for login."
},
{
"type": "text",
"id": "auth0_logout_url",
"label": "Auth0 Logout Url",
"info": "The full Auth0 URL to redirect the customer to for logout."
}
]
}
技術ブログ⑨.png

続いて、URLを作成していきます。
まずは、以下のようにログインURLを作成します。

上記で作成したAuth0アプリケーションのClient IDを取得します。

技術ブログ⑩.png
  • auth0-instance:Auth0ドメイン。(例:sample.jp.auth0.com)
  • clientid:Auth0アプリケーションからの値。
  • shopify-domain:自身のストアのドメイン。
  • return-to-path:任意で返したいパスを設定可能。(例:ログイン後にアカウントページに遷移させたい場合は、accountと設定。)

https://{auth0-instance}/authorize?response_type=code&client_id={clientid}&return_to=https://{shopify-domain}/{return-to-path}&scope=SCOPE&state=STATE

同様にログアウトURLも作成します。

  • auth0-instance:Auth0ドメイン。(例:sample.jp.auth0.com)
  • clientid:Auth0アプリケーションからの値。
  • shopify-domain:自身のストアのドメイン。

https://{auth0-instance}.auth0.com/v2/logout?response_type=code&client_id={clientid}&returnTo=https://{shopify-domain}/account/logout

テーマページに戻り、カスタマイズをクリックして、画面左下に出てくるテーマ設定をクリック、Auth0 Configセクションを展開して、作成したURLを貼り付けます。

技術ブログ⑪.png

以上で実装完了です!

実際の画面遷移

ログインページにて、Log in with Auth0をクリックする。
技術ブログ⑫.png

上記で作ったShopify StoreというAuth0アプリケーションの認証画面が出てくるので、認証情報を入力してログインする。
技術ブログ⑬.png

ログインに成功!
技術ブログ⑭.png

さいごに

最近ではSSOを利用できるサービスがかなり増えてきたなという印象ですが、実際使ってみると本当に便利ですよね。他のアプリケーションでもこのような方法でSSOを導入することができると思いますので、導入を検討する際にはこちらの記事を参考にしていただけますと幸いです。

最後まで読んでいただきありがとうございました!

参考リンク