
Twilio Verify API で始める SMS 認証: Node.js での実装
はじめに
本記事では、 Twilio Verify API を活用して、 Node.js アプリへ SMS 認証を追加する方法について解説します。実際に動作するサンプルコードを通して、認証コードの送信から検証までの一連の流れを確認します。
Twilio とは
Twilio とは、SMS・電話・ビデオ通話などのコミュニケーション機能を、複雑な実装を行うことなく、シンプルなAPIで簡単に導入・運用できるサービスです。Twilio Verify は、電話番号やメールアドレスがその人のものであることを確認するための認証サービスです。 SMS 、音声通話、メールなど複数のチャネルに対応し、ワンタイムパスワード (OTP) による二要素認証を簡単に実装できます。
対象読者
- Node.js の基本的な知識を持つ開発者
- アプリに二段階認証機能を追加したい開発者
- Twilio Verify API の具体的な実装方法を知りたい方
参考
構成
本記事で実装する電話番号認証の全体的な流れを以下に示します。
- ユーザーが電話番号を入力
- アプリは Twilio Verify API に認証コードの送信をリクエスト
- Twilio は SMS 経由でユーザーの電話に認証コードを送信
- ユーザーが受け取った認証コードをアプリに入力
- アプリは再び Twilio API を呼び出してコードの妥当性を検証
- Twilio は検証結果を返却
- アプリはその結果に基づいてユーザーに認証の成否を通知
実装
Twilio コンソールでの準備
Twilio Console にログイン後、ダッシュボードが表示されます。ここで、以下の情報を控えておきます。
- Account SID: アカウントを識別する ID
- Auth Token: API 認証に使用するトークン

次に、 Verify Service を作成します。 Twilio Console の Verify Services ページ にアクセスし、 "Create new" ボタンをクリックします。

以下の項目を設定します。
- Friendly Name: サービスの名前 (例: test)- Authorize the use of friendly name にチェック
 
- Verification channels: 認証チャネル (今回は SMS を選択)

Fraud Guard (不正行為防止機能) の ON/OFF を設定します。 ON 推奨です。

作成が完了すると、 Service SID (例: VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) が発行されます。この Service SID を控えておきます。

Node.js 環境構築
本記事では Node.js v18 以上を使用します。以下のコマンドでバージョンを確認してください。
node --version
新しいディレクトリを作成し、 npm プロジェクトを初期化します。
mkdir twilio-verify-demo
cd twilio-verify-demo
npm init -y
Twilio SDK と Express 、環境変数管理のための dotenv をインストールします。
npm install twilio express dotenv
各パッケージの役割は以下の通りです。
- twilio: Twilio API を呼び出すための公式 SDK
- express: Web サーバーフレームワーク
- dotenv: 環境変数を .envファイルから読み込むためのライブラリ
プロジェクトルートに .env ファイルを作成し、先ほど取得した認証情報を設定します。
TWILIO_ACCOUNT_SID=your_account_sid_here
TWILIO_AUTH_TOKEN=your_auth_token_here
TWILIO_VERIFY_SERVICE_SID=your_verify_service_sid_here
各値は、 Twilio Console で確認した実際の値に置き換えてください。
サンプルコード
最小限の実装で動作する認証 API を作成します。プロジェクトルートに index.js ファイルを作成し、以下のコードを記述してください。
index.js
require('dotenv').config();
const express = require('express');
const twilio = require('twilio');
const app = express();
app.use(express.json());
// Twilio クライアントの初期化
const client = twilio(
  process.env.TWILIO_ACCOUNT_SID,
  process.env.TWILIO_AUTH_TOKEN
);
const verifyServiceSid = process.env.TWILIO_VERIFY_SERVICE_SID;
// 認証コード送信エンドポイント
app.post('/send-verification', async (req, res) => {
  const { phoneNumber } = req.body;
  if (!phoneNumber) {
    return res.status(400).json({ error: '電話番号が必要です' });
  }
  try {
    const verification = await client.verify.v2
      .services(verifyServiceSid)
      .verifications.create({
        to: phoneNumber,
        channel: 'sms'
      });
    res.json({
      success: true,
      status: verification.status,
      to: verification.to
    });
  } catch (error) {
    console.error('認証コード送信エラー:', error);
    res.status(500).json({
      error: '認証コードの送信に失敗しました',
      details: error.message
    });
  }
});
// 認証コード検証エンドポイント
app.post('/verify-code', async (req, res) => {
  const { phoneNumber, code } = req.body;
  if (!phoneNumber || !code) {
    return res.status(400).json({ error: '電話番号と認証コードが必要です' });
  }
  try {
    const verificationCheck = await client.verify.v2
      .services(verifyServiceSid)
      .verificationChecks.create({
        to: phoneNumber,
        code: code
      });
    res.json({
      success: verificationCheck.status === 'approved',
      status: verificationCheck.status
    });
  } catch (error) {
    console.error('認証コード検証エラー:', error);
    res.status(500).json({
      error: '認証コードの検証に失敗しました',
      details: error.message
    });
  }
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`サーバーが起動しました: http://localhost:${PORT}`);
});
上記のコードでは、以下の 2 つのエンドポイントを実装しています。
1. /send-verification エンドポイント
電話番号を受け取り、 Twilio Verify API に認証コードの送信をリクエストします。verifications.create() メソッドを呼び出すことで、指定した電話番号に SMS が送信されます。
2. /verify-code エンドポイント
電話番号と認証コードを受け取り、 Twilio Verify API に検証をリクエストします。verificationChecks.create() メソッドを呼び出すことで、コードの妥当性が検証されます。検証が成功すると status が approved になります。
検証
実行結果の確認
実装したアプリケーションを起動し、実際に動作を確認します。以下のコマンドでサーバーを起動します。
node index.js
正常に起動すると、以下のようなメッセージが表示されます。
サーバーが起動しました: http://localhost:3000
別のターミナルを開き、 curl コマンドで認証コード送信 API を呼び出します。 phoneNumber には、自分の電話番号を国際電話形式 (例: +819012345678) で指定してください。
curl -X POST http://localhost:3000/send-verification \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber": "+819012345678"}'
正常に送信されると、以下のようなレスポンスが返ってきます。
{
  "success": true,
  "status": "pending",
  "to": "+819012345678"
}
指定した電話番号に SMS が届きます。メッセージには 6 桁の認証コードが記載されています。

受け取った認証コードを使って、検証 API を呼び出します。 code には SMS で受け取った 6 桁のコードを指定してください。
curl -X POST http://localhost:3000/verify-code \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber": "+819012345678", "code": "123456"}'
認証コードが正しい場合、以下のようなレスポンスが返ってきます。
{
  "success": true,
  "status": "approved"
}
認証コードが誤っている場合や期限切れの場合は、以下のようなレスポンスになります。
{
  "error": "認証コードの検証に失敗しました",
  "details": "The requested resource /v2/Services/VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/VerificationCheck was not found"
}
まとめ
本記事では、 Twilio Verify API を使用した電話番号認証の最小実装を解説しました。わずか数十行のコードで、認証コードの送信から検証まで、セキュアな SMS 認証機能をアプリに追加できることを確認しました。今後はメールなど他チャネルへの対応など本番環境での運用を見据えた拡張を検討するとよいでしょう。










