BBB bit2byte blog

bit2byte

shopifyのカスタマイズ – 会員登録機能 メール認証の実装方法

2024.09.02.月

井上 飛鳥

Engineer

Shopify APIを使ったカスタマイズ事例:メール認証の実装方法

今回は、Shopify案件において、アプリの使用を最小限に抑えつつ、APIを活用したカスタマイズを行いました。その中でも特にメール認証機能についてご紹介します。

Dawnテンプレートでのメール認証フロー

今回採用したDawnテンプレートでは、会員登録フォームに入力後、確認画面を挟まずにそのまま登録が完了します。これはカナダ仕様かもしれませんが、日本のユーザーにとっては、メールアドレス認証を経由する方が安心感があると考えられます。そのため、ユーザーにとって最適なフローを目指し、以下のようにカスタマイズしました。

カスタマイズ手順

1. メールアドレス検証 -固定ページの作成とAjax処理の追加-

Shopifyでページを作成し、そのページ上でAjaxを使用してメールアドレス検証を行うように処理を記述しました。
jQueryを使ってAjaxリクエストを自前のWebサーバーに送信し、以下の処理を実行しています。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
  $(document).ready(function () {
    $('#emailForm').submit(function (e) {
      e.preventDefault();
      $.ajax({
        url: 'https://your-server-host/shopify/customer/verify',
        method: 'POST',
        data: { email: $('#email').val() },
        success: function (response) {
          // 成功時の処理:登録確認メール送信完了ページへリダイレクト
          location.href = '/pages/register_sended_mail';
        },
        error: function (xhr) {
          // エラーが発生した場合、サーバーからの応答に基づいてメッセージを表示
          var errorMessage = '送信に失敗しました。もう一度試してください。';
          if (xhr.responseJSON && xhr.responseJSON.error) {
            errorMessage = xhr.responseJSON.error;
          }
          $('#error-message p').text(errorMessage);
          $('#error-message').show();
        },
      });
    });
  });
</script>

public function verify(Request $request)
{
    $request->validate(['email' => 'required|email']);
    $email = $request->email;

    // Shopify API で既存の顧客をチェック
    $response = Http::withHeaders([
        'X-Shopify-Access-Token' => $this->accessToken
    ])->get("https://{$this->shopName}/admin/api/2021-07/customers/search.json", [
        'query' => 'email:' . $email
    ]);

    if ($response->json('customers')) {
        return response()->json(['error' => '既に登録済みのメールアドレスです'], 422);
    }

    $token = Str::random(64);
    EmailVerificationModel::updateOrCreate(
        ['email' => $email],
        ['token' => $token, 'expires_at' => now()->addHours(24)]
    );

    Mail::to($email)->send(new VerifyEmail($token));

    return response()->json(['message' => 'Verification email sent.'], 200);
}

入力されたメールアドレスがすでに登録済みでないか、ShopifyのAPIを使ってチェックします。登録済みでない場合は、認証トークンを生成し、メールで送信します。

2. トークンの検証

main-register.liquidのカスタマイズ

今回のカスタマイズでは、会員登録画面のmain-register.liquidも修正を行いました。具体的には、トークンの検証を行い、トークンが正しければ登録画面をそのまま表示、問題がある場合にはエラーメッセージを表示して先に進めないようにしました。

カスタマイズの実装コード

以下は、トークン検証を行うための会員登録画面に追記したjQueryコードです。トークンが有効な場合は、登録フォームにユーザーのメールアドレスが自動的に入力され、ページが正常に表示されます。逆に、トークンが無効な場合は、「不正なリクエストです」というエラーメッセージが表示され、ユーザーが登録を進められないようにします。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
  function verifyToken(token) {
    $.ajax({
      url: 'https://your-server-host/shopify/customer/verify-email',
      method: 'POST',
      data: { token: token },
      success: function(response) {
        if(response.email) {
          $('body').show();
          $('#RegisterForm-Email').val(response.email);
        } else {
          $('body').html('不正なリクエストです');
        }
      },
      error: function(xhr) {
        $('body').show();
        $('body').html('不正なリクエストです');
      }
    });
  }
</script>

サーバー側では以下の処理が行われます。

public function verifyEmail(Request $request)
{
    $token = $request->input('token');
    $verification = EmailVerificationModel::where('token', $token)
                                          ->where('expires_at', '>', now())
                                          ->first();

    if ($verification) {

        // Shopify API で既存の顧客をチェック
        $response = Http::withHeaders([
            'X-Shopify-Access-Token' => $this->accessToken
        ])->get("https://{$this->shopName}/admin/api/2021-07/customers/search.json", [
            'query' => 'email:' . $verification->email
        ]);

        if ($response->json('customers')) {
            return response()->json(['error' => 'Invalid token.'], 401);
        }

        return response()->json([
            'message' => 'Token verified.',
            'email' => $verification->email  // メールアドレスをレスポンスに含める
        ], 200);
    } else {
        return response()->json(['error' => 'Invalid token.'], 401);
    }
}

トークンの有効性を確認し、問題がなければそのまま登録に進みます。

今回のカスタマイズではエックスサーバーを使用し、その中にLaravelをインストールしてAPI処理の実装を行いました。エックスサーバーへのLaravelのインストール方法については、別記事で詳細を紹介予定です。


井上 飛鳥代表取締役

<Web業界との関わり>
Webは20歳のころ自分のHPを作成する事から始まり、当時はHTMLよりもFlash MXでFlashサイトを作ったりしていました。
その後サーバーサイドに興味を持ち、様々な企業様のWeb制作・システム開発に携わらせていただきました。

<会社名Bit2Byteの由来>
企業前からイメージしていたものです。
昔から仕事や悩みなどを1人で抱え込む事が多かったのですが、何事も1人だけではできず、皆の協力で成り立っているものだと深く思い、1人から皆に繋げていく意味を込めて名付けました。

お客様の立場になり問題を解決できるよう会社一丸となって本当に感謝される事を目的としています。

Recommend