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を用いて、ユーザ登録フォームにメールを用いた認証機能を実装していきます!
構築する登録フォームの詳細を下の図に示します。
- ユーザ名、メールアドレス、パスワードをユーザ登録画面に入力する。
- Twilio Verifyから認証コードがメールで通知され、登録画面から検証ページに遷移する。
- ユーザが検証ページで認証コードを入力する。
- 検証ページで入力されたコードをTwilio Verifyが検証する。間違ったコードが入力された場合、認証に失敗した旨が画面上に表示される。
- 認証に成功すると、ユーザの一覧ページが表示される。
必要なもの
- Twilioアカウント
- SendGridアカウント
- SendGrid APIキー(必要な権限についてはこちらを参照)
- Git
- Node.js
- npm(Node.jsに同梱)
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をクリックしてください。
Dynamic Templateの名前を入力したら、Createを押してください。今回は、テンプレート名を「Email-Verification」としました。
Dynamic Templates設定画面に移動したら、下の画面のAdd Versionを押します。
Your Email DesignsのBlank Templateを選択し、次に現れる画面でCode Editorを選択してください。
Dynamic Templateの編集画面が表示されたら、先ほどのHTMLコードをコードエディタに入力しましょう。メールのSubjectは、画面左側のSettingsから設定できます。今回は、Subjectを「Twilio Verify」としました。
以上の設定が完了したら、Saveを押して、画面左上の「←」からDynamic Templates設定画面に戻ってください。
下の画面に表示されている、作成したDynamic TemplateのTemplate IDをメモに控えておきましょう。このTemplate IDは次のStepで使用します。
Step 2: Twilio VerifyとSendGridの連携設定
Twilio Verify Serviceを作成し、二要素認証コードの生成と認証確認機能の設定を行います。Twilio Verifyのコンソール画面に移動し、新しいServiceを作成してください。
Serviceを新規作成すると、作成したServiceのSettings画面が表示されます。後で必要になるので、下の画面のSERVICE SIDをメモに控えておきましょう。
Twilio VerifyからSendGridを介してメール通知するための設定を行います。Email Integration設定画面に移動し、Create Email Integrationを押してください。
以下の画面がポップアップ表示されるので、作成するEmail Integrationの名前を入力し、Continueを押してください。今回は、「Daisuke’s Email Verification」としました。
作成する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()は、認証コードを検証するためのメソッドです。
toとcodeに入力されたメールアドレスと認証コードの組み合わせが、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を押します。
認証に成功し、今回検証したユーザ情報がユーザリストに追加されていることを確認しました!
まとめ
今回は、Twilio VerifyとSendGridを使ったメール認証システムの構築について紹介しました。
ユーザ登録時のメール認証や二要素認証の一連の手続きは、認証コードの生成、通知、検証など多くの手順を含んでおり大変複雑です。しかし、Twilio Verifyを用いることでこれらの手順を簡単に済ませることができます。二要素認証の重要性が増している昨今では、重宝される機能なのではないかと思います。ぜひ皆さんも、この機会にTwilio Verifyに触れてみてはいかがでしょうか。