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

January 09, 2023
執筆者
レビュー担当者
Diane Phan
Twilion
Liz Moy
Twilion

この記事はTwilioデベロッパーエバンジェリストのKelley Robinsonが執筆したこちらの記事(英語)を日本語化したものです。

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

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

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

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

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

電話番号検証の設定

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

このフォームではintl-tel-inputプラグインを使用し、入力内容を国際的なE.164標準に変換しています。入力を標準化し、グローバルなサポートを実現するために、Twilioやほかの多くのAPIがこの形式を使用しています。詳細については、E.164形式で電話番号を入力できるフィールドを作成する方法を紹介したこちらのブログ記事をご覧ください。

以下は、これから紹介する検証オプションのデモで使用するコードです。このコードを、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ブラウザーで開いてアプリケーションをテストしてみましょう。無効な電話番号でもエラーが表示されていないことが分かります。

no error is thrown with invalid phone numebr

このページで適切にエラーが表示されるように修正しましょう。

電話番号の検証方法

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

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

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

今回利用するTwilio Lookup API の番号確認機能は無料で利用でき、任意のバックエンドシステムに組み込めます。本チュートリアルではTwilioが提供するサーバーレスJavaScript Functionsを使用します。

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

この方法ではTwilioアカウントを使用します。アカウントをお持ちでない場合はこちらから無料で登録できます。Twilioコンソールを開いて新しいFunctionサービスを作成します。今回は「intl-tel-input」という名前にします。

日本語作成者による追記: Twilioアカウントの作成方法についてはこちらをご覧ください

ntl-tel-input Twilio Functions service

lookup」という名前の関数を追加します。

"lookup" Twilio Function

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

public lookup function

関数内部のコードを次に置き換えます。

exports.handler = 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');
 
 if (typeof event.phone === "undefined") {
   response.setBody({
     success: false,
     error: "Missing parameter; please provide a phone number.",
   });
   response.setStatusCode(400);
   return callback(null, response);
 }
 
 const client = context.getTwilioClient();
 
 client.lookups
   .phoneNumbers(event.phone)
   .fetch()
   .then((resp) => {
     response.setStatusCode(200);
     response.setBody({
       success: true,
     });
     callback(null, response);
   })
   .catch((error) => {
     console.log(error);
     response.setStatusCode(error.status);
     response.setBody({
       success: false,
       error: error.message,
     });
     callback(null, response);
   });
};

この関数は電話番号を検索し、APIで有効と判断された場合は「success: true」、無効と判断された場合は「false」を返します。

画面下部の[Deploy All]をクリックします。

次のクエリパラメーターを追加し、ブラウザーで関数をテストできます:

http://<実際のプレフィックスをここに挿入>.twil.io/lookup?phone=+18448144627

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

では、アプリケーションからこれを呼び出してみましょう。

index.htmlファイルのprocess関数を以下のコードで置き換えます。fetch呼び出し内のURLを先ほど作成したTwilio Functionの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.log(json.error);
       error.style.display = "";
       error.innerHTML = `Invalid phone number.`;
     }
   })
   .catch((err) => {
     error.style.display = "";
     error.innerHTML = `Something went wrong: ${err}`;
   });
}

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

invalid phone number

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

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

  • メリット: 電話番号の入力にプラグインを使用している場合は、特に記述すべきコードの量が少なくなります。
  • デメリット: 有効な電話番号は時間経過と共に変わります。そのため、プラグイン側によるlibphonenumberの更新に依存することになります。結果として、有効な電話番号を持つユーザーが締め出されてしまう恐れがあります。

先ほどと同様にindex.htmlファイルの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の実装については、Twilio Code Exchangeのこちらのプロジェクトをご覧ください。

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

電話番号の認証についてご質問がある場合は、Twitter @kelleyrobinsonでお問い合わせください。I can’t wait to see what you build.