TwilioのVerify APIでメール認証(OTP)を試してみた
こんにちは、昴です。
今回はTwilioのVerify APIを使って、メールアドレス宛てに認証コード(OTP)を送る「メール認証」を試してみます。
はじめに
Twilioは電話やSMS、チャットなどのコミュニケーション機能を組み込むためのクラウドベースのAPIプラットフォームです。TwilioのAPIを利用することで通信ソリューションを自由にカスタマイズして構築することができます。 以前、Twilio VerifyのTry it outを使ってノーコードでSMS二要素認証を試してみた(https://dev.classmethod.jp/articles/twilio-verify-sms-2fa-nocode/)という記事で、SMSを使った認証コードの送受信をノーコードで体験しました。Twilio Verifyはそれ以外にも「音声通話」「WhatsApp」「メール」など複数のチャネルで認証コードを送ることができます。 今回はその中でも「メール」チャネルにフォーカスして、curlでAPIを叩く形でメールOTP認証を試してみます。メール送信にはTwilioが連携しているSendGridを使用します。
今回の大まかな流れは次のとおりです。
- SendGrid側の準備(Dynamic Template作成・APIキー作成・送信元アドレスの認証確認)
- TwilioのVerify ServiceにEmailチャネルを有効にしたサービスを作成する
- Twilio VerifyにSendGridのEmail integrationを登録する
- APIでOTPを送信・検証する
前提・検証環境
本記事の手順を進めるにあたり、以下の環境および権限が必要です。
- Twilioアカウントが開設済みであること
- SendGridアカウントが開設済みであること(無料プランで可)
- SendGridでSingle Sender認証が完了しているメールアドレスがあること
- curlが使える環境があること(Mac/LinuxのターミナルまたはWindowsのWSL・Git Bash)
- OTPを受信できるメールアドレスがあること
実践
SendGrid側の準備
Dynamic Templateの作成
TwilioがEmailでOTPを送信する際、SendGridのDynamic Templateを使ってメール本文を組み立てます。テンプレート内でHandlebarsの変数 {{twilio_code}} を使うと、送信時にTwilioが自動でOTPコードに置換してくれます。
SendGridコンソール(app.sendgrid.com)にログインし、左メニューの Email API > Dynamic Templates を開きます。

「Create a Dynamic Template」をクリックすると、テンプレート名の入力ダイアログが表示されます。今回は Twilio-Verify-OTP と入力して「Create」をクリックします。

テンプレートが作成され、一覧に表示されます。テンプレートをクリックして展開すると Template ID(d- から始まる文字列)が確認できます。このIDは後でTwilio側の設定に使うので控えておきます。

テンプレートを展開した状態で「Add Version」をクリックし、エディタの選択画面では Blank Template を選んだあと Code Editor を選択します。
HTMLエディタが開くので、左側のコードエリアに以下のHTMLを貼り付けます。{{twilio_code}} の部分がTwilioによってOTPコードに自動置換されます。
<!DOCTYPE html>
<html>
<head>
<title>認証コード</title>
</head>
<body style="font-family: sans-serif; padding: 24px;">
<p>以下の認証コードをご入力ください。</p>
<h2 style="letter-spacing: 4px;">{{twilio_code}}</h2>
<p style="color: #888; font-size: 12px;">このコードは10分間有効です。</p>
</body>
</html>
また、上部の Subject 欄には「認証コード:」と入力します。送信時にTwilioがコードを末尾に自動付加するため、件名は「認証コード: XXXXXX」のような形式で届きます。

入力後、右上の「Save」をクリックしてテンプレートを保存します。
APIキーの作成
左メニューの Settings > API Keys を開きます。初回はキーが存在しない状態です。「Create API Key」をクリックします。

キー名(例:twilio-verify-key)を入力し、アクセス権限はカスタムアクセスを選択します。Twilio Verifyのメール送信に必要な権限はTwilio公式ドキュメントに明記されており、以下の2つのみを設定します。
- Mail Send:Full Access
- Template Engine:Read Access
他の権限はすべてNo Accessのままで問題ありません。セキュリティに関わるサービスで使用するキーなので、不必要な権限は付与しないようにしましょう。

「Create & View」をクリックすると、SG. から始まるAPIキーが表示されます。このキーはこの画面でしか確認できません。必ずコピーして安全な場所に保存してください。

Sender Authenticationの確認
SendGridでメールを送信するには、送信元メールアドレスをSendGrid側で認証しておく必要があります。Settings > Sender Authentication を開き、使用予定の送信元アドレスが「Verified」になっていることを確認します。

認証済みでない場合は「Verify a Single Sender」から認証してください。これでSendGrid側の準備は完了です。
Twilio側の設定
TwilioのVerify Service作成
TwilioコンソールでEmailチャネルを有効にしたVerify Serviceを新規作成します。左メニューの Verify > Services を開きます。

「Create new」をクリックし、ダイアログに以下の内容を入力します。
- Friendly name:My-Email-Verify-Service(任意の名前)
- Verification channels:Email のみオン(SMS・WhatsApp・VoiceはオフでOK)

「Continue」をクリックするとサービスが作成され、Email integrationの設定画面に進みます。
SendGrid Email integrationの登録
サービス作成後、TwilioのVerify側でSendGridとの連携(Email integration)を設定します。「Create new email integration」をクリックします。

ダイアログが開くので、以下の情報を入力します。
| 項目 | 内容 |
|---|---|
| Integration name | My-SendGrid-Integration(Twilioコンソール内でのみ表示される識別名) |
| "From" email address | SendGridで認証済みの送信元アドレス |
| "From" name | 受信者の受信トレイに表示される送信者名(例:Twilio Verify) |
| SendGrid API key | 先ほど作成したAPIキー(SG. から始まる69文字) |
| Template ID | SendGridで作成したDynamic TemplateのID(d- から始まる文字列) |

「Create」をクリックします。作成に成功すると Integration settings ページに遷移し、Email integration SID(MD から始まる文字列)が発行されます。

Verify ServiceのEmailタブで統合を選択
続いて、作成したVerify Serviceと今回設定したEmail integrationを紐付けます。左メニューで My-Email-Verify-Service > Settings に移動し、「Email」タブを開きます。
「Select or change the existing email integration」のドロップダウンから先ほど作成した My-SendGrid-Integration を選択し、「Save」をクリックします。

これでTwilio VerifyとSendGridの連携設定が完了しました。
確認
PowerShell上でcurl.exeを使い、OTPの送信と検証を試します。事前に環境変数として TWILIO_ACCOUNT_SID・TWILIO_AUTH_TOKEN・VERIFY_SERVICE_SID を設定しておきます。
$env:TWILIO_ACCOUNT_SID = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$env:TWILIO_AUTH_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$env:VERIFY_SERVICE_SID = "VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
OTPの送信
以下のコマンドで、指定したメールアドレス宛にOTPを送信します。Channel=email を指定するのがポイントです。
curl.exe -X POST "https://verify.twilio.com/v2/Services/$env:VERIFY_SERVICE_SID/Verifications" `
--data-urlencode "To=送信先メールアドレス" `
--data-urlencode "Channel=email" `
-u "$($env:TWILIO_ACCOUNT_SID):$($env:TWILIO_AUTH_TOKEN)"
レスポンスの "status": "pending" はOTPが正常に送信中であることを示しています。

しばらくすると、SendGridを経由してメールが届きます。件名は 認証コード: [OTPコード] となり、本文にはSendGridのテンプレートで設定した内容が表示されています。{{twilio_code}} の部分が実際のOTPコードに置換されているのが確認できます。

コードの検証(正しいコード)
メールに記載されているコードを使って検証します。
curl.exe -X POST "https://verify.twilio.com/v2/Services/$env:VERIFY_SERVICE_SID/VerificationCheck" `
--data-urlencode "To=送信先メールアドレス" `
--data-urlencode "Code=メールに記載されたコード" `
-u "$($env:TWILIO_ACCOUNT_SID):$($env:TWILIO_AUTH_TOKEN)"
レスポンスの "status": "approved"・"valid": true で認証成功を確認できます。

コードの検証(誤ったコード)
あえて間違ったコード(000000)を入力した場合の挙動も確認してみます。
curl.exe -X POST "https://verify.twilio.com/v2/Services/$env:VERIFY_SERVICE_SID/VerificationCheck" `
--data-urlencode "To=送信先メールアドレス" `
--data-urlencode "Code=000000" `
-u "$($env:TWILIO_ACCOUNT_SID):$($env:TWILIO_AUTH_TOKEN)"
"valid": false が返り、誤ったコードは認証されないことが確認できます。

まとめ
今回はTwilioのVerify APIをメールチャネルで使い、OTP認証を試してみました。 SMSとチャネルを変えるだけで同じAPIの仕組みが使えるので、様々なユースケースにも簡単に対応できることが分かりました。 本ブログが少しでも参考になれば幸いです。
告知
Twilio/SendGridセミナーを毎月開催しています
クラスメソッドでは毎月Twilio/SendGridのセミナーを実施しています。
クラスメソッドではTwilio/SendGridのセミナーを毎月開催しております。いずれもTwilio及びSendGridを良く知らない方向けに基本的な部分から解説する内容となっておりますので、今後Twilio/SendGridの導入を検討している方や、既に導入済で改めて基本的な部分を勉強したいと考える方は、是非お気軽にご参加いただければと思います。





