HTMLとJavaScriptで電話番号の入力を検証する方法

April 15, 2024
執筆者
レビュー担当者
Diane Phan
Twilion
Liz Moy
Twilion

今回のブログは、「電話番号 正規表現」を検索して後悔したことがある方に最適です。電話番号の形式として有効なものは数多くありますが、電話番号が有効かどうかを確認するのに役立つ無料のツールもあります。

今回の投稿では、Twilio Lookup APIとintl-tel-input JavaScriptプラグインを使用して電話番号の有効性をチェックする2つの方法についてご紹介します。今回の内容は「HTML/JavaScriptで国際電話番号入力を作成する方法」をベースにしています。こちらの投稿では、今回の投稿で紹介しているような美しい電話番号入力フィールドの作成に関する詳細を確認できます。

完成したコードをGitHubで参照できます。

電話番号入力を検証する理由

電話番号を検証することによりサインアップのスパムと不正を防止できるだけでなく、入力ミスなどの単純ミスも検知できます。このブログの最後に、電話認証における推奨事項とアカウントセキュリティに関するベストプラクティスを紹介しています。というのも、電話番号が有効なものであるかどうかだけでなく、その電話番号がユーザー自身のものであることも通常は確認する必要があるからです。

電話番号検証の設定

なかには、電話番号の入力欄がすでに用意されている場合があります。これから作成しようという場合、電話番号の入力を受け付けるシンプルなHTMLページを使用することをお勧めします。

This form uses the intl-tel-input plugin which processes the input to the international E.164 standard. This format is used by many APIs, including Twilio's, to ensure standardized input and global support. You can read more about how to build a phone number input field that can provide the E.164 format in this blog post.

以下は、これから紹介する検証オプションのデモで使用するコードです。このコードを、index.htmlというファイルの中に貼り付けてください。

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>International telephone input</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="styles.css" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/css/intlTelInput.css"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/intlTelInput.min.js"></script>
  </head>
  <body>
    <div class="container">
      <form id="login" onsubmit="process(event)">
        <p>Enter your phone number:</p>
        <input id="phone" type="tel" name="phone" />
        <input type="submit" class="btn" value="Verify" />
      </form>
      <div class="alert alert-info" style="display: none"></div>
      <div class="alert alert-error" style="display: none"></div>
    </div>
  </body>
  <script>
    const phoneInputField = document.querySelector("#phone");
    const phoneInput = window.intlTelInput(phoneInputField, {
      utilsScript:
        "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",
    });

    const info = document.querySelector(".alert-info");
    const error = document.querySelector(".alert-error");

    function process(event) {
      event.preventDefault();

      const phoneNumber = phoneInput.getNumber();

      info.style.display = "";
      info.innerHTML = `Phone number in E.164 format: <strong>${phoneNumber}</strong>`;
    }
  </script>
</html>

スタイルを整えるにはGitHubからスタイルシートを取得し、index.htmlと同じフォルダにあるstyles.cssというドキュメントにこのスタイルシートを配置してください。

HTMLファイルをWebブラウザーで開いてアプリケーションをテストしてみましょう。無効な電話番号でもエラーがスローされていないことが分かります。

 

無効な電話番号を入力してもエラーが表示されていない

 

エラーがスローされるように修正しましょう。

電話番号の検証方法

電話番号を検証する方法として、今回は以下の2つを紹介します。

  1. Twilio Lookup APIを使用する
  2. intl-tel-inputプラグインを使用する

Twilio Lookup APIを使用した電話番号の検証

Twilio Lookup APIのリクエストは無料であり、任意のバックエンドに埋め込むことができます。今回のチュートリアルではTwilioのサーバーレスJavaScript関数を使用します。

  • メリット: 電話番号の有効性データをLookup APIが更新済です。このAPIを使用して回線種別やキャリアを確認することもできます。
  • デメリット: コードが長くなり、ネットワークリクエストの数も増えます。

このパートではTwilioアカウントを使用します。アカウントをお持ちでない場合はこちらから無料で登録できます。Twilio Consoleを開いて関数サービスを作成します。ここでは「intl-tel-input」という名前にします。

 

「intl-tel-input」という名前のTwilio関数サービス

関数を追加して「lookup」という名前を付けます。

「lookup」という名前のTwilio関数

Twilioの外部から呼び出すため、関数タイプを「public」に設定するのを忘れないようにしてください。

関数タイプが「public」に設定された「lookup」関数

コードを次のコードで置き換えます。

function errorStr(errors) {
  return errors
    .map((err) => {
      return err.replaceAll("_", " ").toLowerCase();
    })
    .join(", ");
}

exports.handler = async function (context, event, callback) {
  const response = new Twilio.Response();
  response.appendHeader("Content-Type", "application/json");
  response.appendHeader('Access-Control-Allow-Origin', '*');
  response.appendHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
  response.appendHeader('Access-Control-Allow-Headers', 'Content-Type');
  
  try {
    if (typeof event.phone === "undefined") {
      throw new Error("Missing parameter: please provide a phone number.")
    }

    const client = context.getTwilioClient();
    const lookup = await client.lookups.v2.phoneNumbers(event.phone).fetch();

    if (!lookup.valid) { 
      throw new Error(`Invalid phone number ${event.phone}: ${errorStr(
        lookup.validationErrors
      )}`)
    }

    response.setStatusCode(200);
    response.setBody({
      success: true,
    });
    callback(null, response);
  } catch (error) {
    console.error(error);
    response.setStatusCode(400);
    response.setBody({
      success: false,
      error: error.message
    })
    callback(null, response);
  }
};

Update the twilio library dependency to version 4.23.0 or later before you deploy your Twilio function. From the Twilio Console function editor, navigate to Settings & More >> Dependencies to make changes.

この関数は電話番号を検索し、APIで有効と判断された場合は「success: true」、無効と判断された場合は「false」を返します。無効な電話番号の場合、関数は「too short」(短すぎる)、「too long」(長すぎる)、「invalid country code」(無効な国コード)、「not a number」(数字ではない)などの理由をカンマ区切りで返します。

画面下部の[Deploy All](すべてデプロイ)をクリックします。

次のクエリパラメータを追加することにより、ブラウザーで関数をテストできます: http://<実際のプレフィックスをここに挿入>.twil.io/lookup?phone=+18448144627

{"success":true}と表示されます。

では、アプリケーションからこれを呼び出してみましょう。 process関数を次のように置き換えます。fetch内のURLをTwilio関数のURLに変更するのを忘れないようにしてください。

function process(event) {
 event.preventDefault();

 const phoneNumber = phoneInput.getNumber();

 info.style.display = "none";
 error.style.display = "none";

 const data = new URLSearchParams();
 data.append("phone", phoneNumber);

 fetch("http://<your-url-here>.twil.io/lookup", {
   method: "POST",
   body: data,
 })
   .then((response) => response.json())
   .then((json) => {
     if (json.success) {
       info.style.display = "";
       info.innerHTML = `Phone number in E.164 format: <strong>${phoneNumber}</strong>`;
     } else {
       console.error(json.error);
       error.style.display = "";
       error.innerHTML =  json.error;
     }
   })
   .catch((err) => {
     error.style.display = "";
     error.innerHTML = `Something went wrong: ${err}`;
   });
}

無効な番号を入力すると、エラーメッセージと該当する理由が表示されます。

invalid phone number '123': 'too short'

intl-tel-inputプラグインを使用した電話番号の検証

こちらの投稿プラグインのドキュメントに記載された手順に従いintl-tel-inputをサイトに追加するか、上記のHTMLコードを使用します。intl-tel-inputプラグインでは美しい入力フォームを作成できるだけでなく、Googleのlibphonenumberに対応したラッパーが用意されており、有効な電話番号と無効な電話番号を検出できます。

  • メリット: 特に、電話番号の入力にプラグインを使用している場合はコードの量が少なくなります。
  • デメリット: 有効な電話番号は変わるため、libphonenumberの更新を検するためにプラグインの更新に頼ることになります。有効なユーザーが締め出されてしまう恐れがあります。

process関数を次のコードで置き換えます。

function process(event) {
 event.preventDefault();

 const phoneNumber = phoneInput.getNumber();

 info.style.display = "none";
 error.style.display = "none";

 if (phoneInput.isValidNumber()) {
   info.style.display = "";
   info.innerHTML = `Phone number in E.164 format: <strong>${phoneNumber}</strong>`;
 } else {
   error.style.display = "";
   error.innerHTML = `Invalid phone number.`;
 }
}

結果はLookup APIの場合と同じになるはずです。

どちらも電話番号の認証では信頼性の高い方法ですが、Lookup APIを使うことをお勧めします。いずれにしても、電話認証を開始し、ユーザーをデータベースに保存するためにこの時点でAPIリクエストを行うことになるからです。

アカウントのセキュリティに関するベストプラクティス

電話番号の検証は、不正を防止し、アプリケーションとユーザーのデータを保護する方法のうちの1つに過ぎません。

私は常日頃から電話認証を推奨しています。認証の方法は限られていますが、ワンタイムパスコード(OTP)を電話番号宛てに送信することは、ユーザーが電話番号を初めて入力する際に所有権を確認する優れた方法です。単純なタイプミスや、ユーザー本人のものではない番号の入力も防止できます。Twilio Verify APIを使用したOTPの実装の詳細については、こちらをご覧ください。

次の記事も役に立つでしょう。

お客様の成功が私たちの喜びです。