shopifyのカスタマイズ – 会員登録機能 メール認証の実装方法
2024.09.02.月
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のインストール方法については、別記事で詳細を紹介予定です。