Twilio VerifyとTwilio Functionsによるサーバーレス電話認証

June 15, 2020
執筆者

Serverless Verify

この記事はTwilioデベロッパーエバンジェリストのKelley Robinsonが執筆したこちらの記事(英語)を日本語化したものです。日本語化作業時点(2022年8月)の状況に合わせて記事内のコードを一部、変更しています。

セキュリティは誰もが気になる項目でしょう。その中で電話認証はアプリケーションの保護やbotアカウントの防止に役立つ簡単な方法と言えます。そのため、ユーザーの電話番号にワンタイムパスワードを送信して所有番号の検証をするやり方は、製品の登録時や電話番号の初回登録時によく使われる方法です。

ユーザーの電話番号を確認することで、不正の低減や通知の信頼性を高められます。今回は、TwilioのサーバーレスファンクションとTwilio Verify APIを使用してWebアプリケーションから電話番号を検証する方法を紹介します。

クイックリンク:

Twilio Verifyをアプリケーションに追加するための前提条件

この記事に沿ってコーディングを行う際に必要なもの:

Twilioコンソールで作成したVerifyサービスのService SID(先頭がVA)を控えておきます。

Verify Service SID

Twilioを利用する場合、APIキーが漏洩する可能性を避けるため、キーを直接フロントエンドアプリケーションに格納しないようにします。通常はセキュリティ強化のためにバックエンドサーバーを使用しそこでVerify APIと通信を行います。今回はバックエンドサーバーとしてTwilio Functionsを使用します。

使用しているOS用のTwilio CLIをインストールし、Twilioアカウントにログインします。

twilio login

次に、サーバーレスツールキットをインストールします。このツールキットを用いることにより認証テンプレートの複製やプロジェクトの配備が簡単に行えます。

# Install the Serverless plugin
twilio plugins:install @twilio-labs/plugin-serverless
 
# See a list of available commands:
twilio serverless

新規プロジェクトを開始します(Verifyファンクションテンプレートを使用)。

twilio serverless:init verify-sample --template=verify && cd verify-sample

付属の.envファイルを編集し、VERIFY_SERVICE_SIDに値を設定します。(コンソールでVerifyサービスを検索/作成)。また、ACCOUNT_SIDAUTH_TOKENの値が入力されていることを確認します。これらの値はtwilio loginを実行すると、サーバーレスツールキットにより設定されます。結果、.envファイルは次のようになります。

日本語版作成者による追記: AUTH_TOKEN の値が入力されていない場合は、Twilioコンソールで確認します。

ACCOUNT_SID=ACxxx
AUTH_TOKEN=g41xxx
 
VERIFY_SERVICE_SID= VAxxx

アプリケーションのローカル実行とテスト

アプリケーションをローカルで起動します。

twilio serverless:start

ブラウザーでhttp://localhost:3000/index.htmlを表示し、ユーザー認証アプリケーションを確認してください。

otp project screenshot

SMSを選択して電話番号を入力します。ボタンをクリックすると入力した電話番号に認証コードが送られます。アプリケーション側で送られてきたコードを入力し、正しければ認証の成功が伝えられます。

verification success view

 

Twilio Verifyの機能

今回のプロジェクトには、認証の開始確認を行う2つの関数が含まれます。

  • 最初にstart関数からエンドユーザーの電話、あるいはメールアドレスに、ワンタイムパスコード(OTP)を送ります。Twilio VerifyがOTPの生成を処理するため、通知方法を選択するだけで済みます。
  • 次にcheck関数にて、OTPがユーザー宛に送信したものと同じであることを検証します。これもTwilio VerifyがOTPの保存と検証を処理するため、独自に実装する必要はありません。

認証のstart関数は次のとおりです。

日本語版作成者による追記: 2022年8月現在のコードに変更しています。

    const verification = await client.verify
      .services(service)
      .verifications.create({
        to,
        channel,
        locale,
      });

    console.log(`Sent verification: '${verification.sid}'`);
    response.setStatusCode(200);
    response.setBody({ success: true });
    return callback(null, response);
  } catch (error) {
    const statusCode = error.status || 400;
    response.setStatusCode(statusCode);
    response.setBody({
      success: false,
      error: error.message,
    });
    return callback(null, response);
  }
};

この関数でユーザーに対して認証を開始します。この際、チャネルロケールは画面で指定したものが使用されます。チャネルはsmscallemail*のいずれかを選択できます。また、ロケールにより認証に使用する言語が決まります。サポートされる言語についてはこちらで確認できます。

*注: メールを使用する場合は追加の設定が必要です。こちらの手順でメール送信のVerifyサービスを設定します。

認証のcheck関数は次のとおりです。

日本語版作成者による追記: 2022年8月現在のコードに変更しています。

    const check = await client.verify
      .services(service)
      .verificationChecks.create({ to, code });

    if (check.status === 'approved') {
      response.setStatusCode(200);
      response.setBody({
        success: true,
        message: 'Verification success.',
      });
      return callback(null, response);
      // eslint-disable-next-line no-else-return
    } else {
      throw new Error('Incorrect token.');
    }
  } catch (error) {
    console.error(error.message);
    response.setBody({
      success: false,
      message: error.message,
    });
    return callback(null, response);
  }
};

この関数からVerificationCheckエンドポイントが呼び出され、ステータスがapprovedであるかどうかを確認されます。認証コードが正しくない場合、応答のstatuspendingとなります。

Twilioサーバーレス関数の展開

前述のようにテンプレートのUIからVerify APIの機能を体験できますが、バックエンドに実装されている2つの関数は長期的に使用でき、本番環境でも使用できます。もしこの関数をサーバーレス実行環境に配備する場合は次のコマンドを使用します。

twilio serverless:deploy

配備後、verify-sample-1234-dev.twil.ioのようにプレフィックスが3つ付いたURLが表示されます(実際の表記は環境によって異なります)。表示されたindexファイル(Assets以下のURL)にアクセスし、再び認証をテストします。

deployed serverless function

もし実装されているコードをローカル環境で変更した場合は、再度twilio serverless:deployコマンドを実行し、関数を更新してください。配備された関数は既存のアプリケーションから使用し、認証の送信と確認に利用できます。

次のステップ

今回は2つのAPI呼び出しと1つのWebページだけでユーザーが実際の電話番号/メールアドレスを所有していることを検証し、該当する連絡チャネルへのアクセスを確認しました。この方式を利用することで多くの不正アカウントを防止し、連絡先の確認を取ることができ、さらに許可を得ているユーザーに対してアプリケーションからテキストや音声の通知を確実に送れます。

今回の記事で使用したサンプルはGitHubのコードを利用するか、独自にTwilio Code Exchangeを使用して2分足らずで配備できます。ユーザー認証やアカウントセキュリティについて不明な点があれば、コメントまたはTwitterでお知らせください。