1
1

More than 3 years have passed since last update.

TwilioのAuthyの2FA(電話番号認証)機能をnode.jsから使う

Last updated at Posted at 2019-12-15

呼び出し方は本家のAPI使う方法や先人のnpmパッケージ使う方法とかあるが、今回は先人のnpmパッケージを利用してみる。

ちなみにTwilioでは2つの電話番号認証機能があり、どちらを使うかはケースバーケースのようです。

Authy API

Authyが提供するAPIはSMS送信以外での2FAに対応していますが、今回はSMS送信による認証を試してみます。

準備

Twilioに登録

Twilioに登録して利用できるようにしておく。無料枠もあるがすぐに消費してしまいます・・・。

Authyのプロジェクト作成とAPIの取得

左メニューからAuthyを選択肢、新規プロジェクトを作成、設定にてPRODUCTION API KEYを取得します。

APIの機能(利用の流れ)

利用方法は簡単で、主な利用APIは下記の2つ。

  • verification_start()でSMS経由でCode送信
  • verification_check()でCode検証

あとは、

  • verification_status()というAPIで状態を確認

することもできる。

実装

まず、モジュールをインストールします。

npm install --save authy

で、実装。

以下のコードではめんどくさいの一気に記述していますが1)と2)は同時に実行することはできません。
まず、2)をコメントアウトして実行し、SMSが届くか見ましょう。そして、1)をコメントアウトして、Codeを設定した状態で2)をコメントインして実行します。

//取得したAPIで初期化
var authy = require('authy')('MswmXqxxxxxxxxxxxxxxxxxxxxxxxxxxx');

const phoneNumber = '9012345678';
const countryCode = '81';
const verificationCode = '000000'; //受け取ったものを入れる

//1)smsでcode送信
authy.phones().verification_start(phoneNumber, countryCode, { via: 'sms', locale: 'ja', code_length: '6' }, (err, res) => {
    if (err) throw err;
    console.log(res);
});

//2)受け取ったコード認証
authy.phones().verification_check(phoneNumber, countryCode, verificationCode, (err, res) => {
    if (err) throw err;
    console.log(res);
});

//3)ステータス確認
authy.phones().verification_status(phoneNumber, countryCode, (err, res) => {
    if (err) throw err;
    console.log(res);
})

スムーズにうまく動きました。

レスポンス

それぞれ、下記のようなレスポンスがあります。

send時。キャリアとかも見える。

{
  carrier: 'NTT DoCoMo',
  is_cellphone: true,
  message: 'テキストメッセージは、+81 111-222-0000 に送信',
  seconds_to_expire: 439,
  uuid: '74dff830-0f49-0138-219c-12b9a9198221',
  success: true
}

check。

{ 
  message: 'Verification code is correct.',
  success: true
}

checkがOKならverified。チェックが終わってないないとpenddingとなる。

{
  message: 'Phone Verification status.',
  status: 'verified',
  seconds_to_expire: 305,
  success: true
}

その他

テストするなら上記コードでも問題ないのですが、関数化するときなどcallbackがやっかいなので、そういう場合はラップしてasync/awaitで利用できるようにしてやる。

例えばFirebase Functions内で利用するときなど下記のようにしてみました。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const authy = require('authy')('MswmXqxxxxxxxxxxxxxxxxxxxxxxxxxxx');

const verification_start_wrapper = (phoneNumber) => {
    return new Promise((resolve, reject) => {
        authy.phones().verification_start(phoneNumber, '81', { via: 'sms', locale: 'ja', code_length: '6' }, (err, res) => {
            if (err) {
                reject(err);
            } else {
                resolve(res);
            }
        })
    });
}

//sendCode
module.exports = functions.https.onCall(async (data, context) => {

    //受け取り
    const tel = data.tel;

    //authy
    const res = await verification_start_wrapper(tel);
    return res;

});

メモ

  • 一度認証しても、再度送信するとstatusはpendingになるようです(まあ、当然ですが)。
  • 料金は国内3キャリア向けに$0.08円(まあ10円)。
  • あくまで電話番号の実在確認なので、会員管理システム等は別途用意しておく必要がある。
  • 専門サービスだけあって090と記述しても送信してくれる。090-1234-5678とハイフンがあっても処理してくれる。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1