Twilio VerifyとSendGridを使ったメール認証機能の実装

Twilio VerifyとSendGridを使ったメール認証機能の実装

SendGridサポートチームの青木です。

今回は、Twilioのブログ「Email Verification with Twilio Verify and Twilio Sendgrid with Node.js」で取り上げられた、Twilio VerifyとSendGridを使ったメール認証機能の実装方法について紹介します!

今回実装するメール認証システムについて

Twilio Verifyは、音声、SMS、メールを用いた二要素認証の仕組みをWebアプリケーションに実装することができる機能です。今回は、Twilio VerifyとSendGridを用いて、ユーザ登録フォームにメールを用いた認証機能を実装していきます!
構築する登録フォームの詳細を下の図に示します。

メール認証システムについて

  1. ユーザ名、メールアドレス、パスワードをユーザ登録画面に入力する。
  2. Twilio Verifyから認証コードがメールで通知され、登録画面から検証ページに遷移する。
  3. ユーザが検証ページで認証コードを入力する。
  4. 検証ページで入力されたコードをTwilio Verifyが検証する。間違ったコードが入力された場合、認証に失敗した旨が画面上に表示される。
  5. 認証に成功すると、ユーザの一覧ページが表示される。

必要なもの

SendGridはFreeプランのアカウント、Twilioは無料トライアルアカウントで構いません。なお、今回の記事ではNode.js 14.16.0を使いました。対応しているバージョンはこちらからご確認ください。

手順

Step 1: メールテンプレートの作成

まずは、認証コードを送るメールをDynamic Templateで作成しましょう。
今回は以下のHTMLコードを用います。
HTMLコード内の{{twilio_code}}に、Twilio Verifyが発行した認証コードが格納されます。

<html>
  <head>
    <style type="text/css">
      body, p, div {
        font-family: Helvetica, Arial, sans-serif;
        font-size: 14px;
      }
      a {
        text-decoration: none;
      }
    </style>
    <title></title>
  </head>
  <body>
  <center>

    <p>
      The verification code is: <strong>{{twilio_code}}</strong>
    </p>
    <p><a href="https://sendgrid.com/blog/open-source-transactional-email-templates/">Check out more templates</a></p>
    <span style="font-size: 10px;"><a href=".">Email preferences</a></span>
  </center>
  </body>
</html>

続いて、SendGridダッシュボードに移動し、Create a Dynamic Templateをクリックしてください。

Create a Dynamic Templateをクリック

Dynamic Templateの名前を入力したら、Createを押してください。今回は、テンプレート名を「Email-Verification」としました。

Createを押す

Dynamic Templates設定画面に移動したら、下の画面のAdd Versionを押します。

Add Versionを押す

Your Email DesignsのBlank Templateを選択し、次に現れる画面でCode Editorを選択してください。

Blank Templateを選択

Code Editorを選択

Dynamic Templateの編集画面が表示されたら、先ほどのHTMLコードをコードエディタに入力しましょう。メールのSubjectは、画面左側のSettingsから設定できます。今回は、Subjectを「Twilio Verify」としました。

HTMLコードをコードエディタに入力

「Twilio Verify」

以上の設定が完了したら、Saveを押して、画面左上の「←」からDynamic Templates設定画面に戻ってください。

下の画面に表示されている、作成したDynamic TemplateのTemplate IDをメモに控えておきましょう。このTemplate IDは次のStepで使用します。

Template IDをメモ

Step 2: Twilio VerifyとSendGridの連携設定

Twilio Verify Serviceを作成し、二要素認証コードの生成と認証確認機能の設定を行います。Twilio Verifyのコンソール画面に移動し、新しいServiceを作成してください。

新しいServiceを作成

Serviceを新規作成すると、作成したServiceのSettings画面が表示されます。後で必要になるので、下の画面のSERVICE SIDをメモに控えておきましょう。

SERVICE SIDをメモ

Twilio VerifyからSendGridを介してメール通知するための設定を行います。Email Integration設定画面に移動し、Create Email Integrationを押してください。

Create Email Integration

以下の画面がポップアップ表示されるので、作成するEmail Integrationの名前を入力し、Continueを押してください。今回は、「Daisuke’s Email Verification」としました。

Email Integrationの設定画面

作成するEmail Integrationの設定画面が表示されるので、以下の情報を入力してください。

  • SENDGRID API KEY:SendGridのAPIキー
  • *DEFAULT TEMPLATE ID:Step 1で作成したDynamic TemplateのTemplate ID
  • *DEFAULT FROM EMAIL:検証メールのヘッダFromに表示されるメールアドレス(お好きなアドレスで構いません)
  • *DEFAULT FROM NAME:メール送信元の名前

必要情報を入力

メール機能を連携させるVerify Serviceをチェックボックスで選択したら、最後は忘れずにSaveを押しましょう。

Step 3: 動作確認

認証コードの発行

ローカル環境にテスト用のフォルダを作成し、Node.jsのTwilio helper libraryをインストールしましょう。
作成したフォルダに移動し、ターミナル上で次のコマンドを実行してください。

npm init
npm install twilio
touch index.js

index.jsに以下のスクリプトを入力しましょう。
重要な認証情報などはスクリプト内に直接書き込まず、環境変数を用いて呼び出すようにします。環境変数の設定方法の詳細は、こちらの記事を参考にしてください。

//環境変数からTwilioのAccount SIDとAuth Tokenを取得する
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;

const twilioClient = require("twilio")(accountSid, authToken);

twilioClient.verify
  .services("VAXXXXXXXXXXX") //Service SIDをここに入力
  .verifications.create({to: "yourtestemail@example.com", channel: "email"})
  .then(verification => {
    console.log(verification.sid);
  });

9行目のverifications.create()では、toで認証コードの通知先、channelで通知方法を指定します。toにはメールアドレスまたは電話番号が入ります。channelにはemail, sms, callが指定可能で、それぞれメール、SMS、音声通知を表します。

今回はメールで通知するため、toにメールアドレスを、channelにemailを指定してください。

ターミナルに戻ったら、次のコマンドでindex.jsを実行してください。

node index

上手く実行できれば、今回用いたTwilio Verifyのリソースを識別するverification SIDがターミナル上に表示され、メールボックスに以下のようなメールが届くはずです。

メール

認証コードの確認

先ほどのスクリプトを実行することで、認証コードが発行されました。続いて認証コードを検証する機能を試してみましょう。実行したスクリプトから、認証コードを生成する9~12行目をコメントアウトし、以下のスクリプトをindex.jsに追加してください。

twilioClient.verify
  .services("VAXXXXXXXXXXX") //Service SIDをここに入力
  .verificationChecks.create({ to: "yourtestemail@example.com", code: "123456" })
  .then(verification_check => console.log(verification_check.status));

verificationChecks.create()は、認証コードを検証するためのメソッドです。
tocodeに入力されたメールアドレスと認証コードの組み合わせが、verifications.create()で生成した認証コードに一致するかどうかをTwilio Verifyが確認します。

試しに、3行目のcodeに間違った認証コードを入力してindex.jsを実行してみましょう。そうすると、ターミナル上にpendingの文字が表示されるはずです。正しい認証コードが入力されるまでは、ステータスとしてpendingが返ります。
次に、メールで受け取った正しい認証コードを試してみてください。
今度は、ターミナル上にapprovedのステータスが表示されるはずです。

以上でTwilio Verifyの動作確認は終了です!
次のステップでは、実際のアプリケーションの実装に移ります。

Step 4: アプリケーションの実装

Twilio Verifyの機能をユーザ登録画面に組み込んでみましょう。今回は、GitHubにあるサンプルアプリケーションを用いて実装していきます。
ターミナル上で以下のコマンドを実行して、サンプルアプリケーションのインストールおよび依存関係の解決を行ってください。

git clone https://github.com/nokenwa/verify-Starter.git
cd verify-Starter
npm install

次のコマンドで.envファイルを作成し、Twilio Account SIDとAuth Token、Twilio Verify SIDを作成した.envファイルに記入しましょう。

cp .env.sample .env

以下のコマンドを実行すると、Webサーバが立ち上がります。

npm start

ブラウザ上でlocalhost:3000にアクセスすると、下のようなユーザ登録ページが表示されるはずです。

ユーザ登録ページ

このユーザ登録ページは、スクリプトで実装した簡易的なデータベースを用いて構築しています。
index.jsの中でユーザ情報を取得してデータベースに格納し、検証メールを送信する部分を下に抜粋します。
検証メールを送信したら/verify(検証ページ)にリダイレクトして、検証コードの入力を求めます。このとき、ユーザのメールアドレスをURLのクエリパラメータとして渡します。これはセッション変数を用いた方法で書いても構いません。

//New User Created
app.post("/", (req, res) => {
  const email = req.body.email;

  database.addUser({
    username: req.body.username,
    email: email,
    password: req.body.password,
    verified: "Not Verified"
  });

  //CREATE A NEW VERIFICATION HERE
  twilioClient.verify
    .services(verificationSID)
    .verifications.create({ to: email, channel: "email" })
    .then(verification => {
      console.log("Verification email sent");
      res.redirect(`/verify?email=${email}`);
    })
    .catch(error => {
      console.log(error);
    });

  // res.redirect("/users");
  
});

以上で、新しいユーザが追加されるたびに、検証メールの送信および/verifyへのリダイレクトが行われるようになりました!

続いて、検証情報を/verifyにPOSTする部分を見てみましょう。
この部分では、ユーザのメールアドレスとコードの組み合わせを確認しています。approvedが検証結果として返った場合は、コードが承認されたことを表示し、ユーザの一覧ページにリダイレクトします。approvedが返らなかった場合は、検証が失敗したことを示すメッセージを表示します。

//Verification Code submission
app.post("/verify", (req, res) => {
  const userCode = req.body.code;
  const email = req.body.email;

  console.log(`Code: ${userCode}`);
  console.log(`Email: ${email}`);

  //CHECK YOUR VERIFICATION CODE HERE

  twilioClient.verify
    .services("VAXXXXXXXXXX")
    .verificationChecks.create({ to: email, code: userCode })
    .then(verification_check => {
      if (verification_check.status === "approved") {
        database.verifyUser(email);
        res.redirect("users");
      } else {
        res.render("verify", {
          email: email,
          message: "Verification Failed. Please enter the code from your email"
        });
      }
    })
    .catch(error => {
      console.log(error);
      res.render("verify", {
        email: email,
        message: "Verification Failed. Please enter the code from your email"
      });
    });
});

結果

それではブラウザに戻って、実際にユーザ登録を進めてみましょう。

ユーザ名とメールアドレス、パスワードを入力してSign Upを押すと、認証コードがメールで送られました。

認証コード

コードを入力

ブラウザ上では検証ページが表示されるので、メールで受け取ったコードを入力してVerifyを押します。

コードを入力してVerifyを押す

認証に成功し、今回検証したユーザ情報がユーザリストに追加されていることを確認しました!

ユーザリストに追加されていることを確認

まとめ

今回は、Twilio VerifyとSendGridを使ったメール認証システムの構築について紹介しました。
ユーザ登録時のメール認証や二要素認証の一連の手続きは、認証コードの生成、通知、検証など多くの手順を含んでおり大変複雑です。しかし、Twilio Verifyを用いることでこれらの手順を簡単に済ませることができます。二要素認証の重要性が増している昨今では、重宝される機能なのではないかと思います。ぜひ皆さんも、この機会にTwilio Verifyに触れてみてはいかがでしょうか。

参考記事

メールを成功の原動力に

開発者にもマーケターにも信頼されているメールサービスを利用して、
時間の節約、スケーラビリティ、メール配信に関する専門知識を手に入れましょう。