FirebaseでSMS認証(Nuxt, Vue.js)


ドキュメント見るの辛い人向けに置いておきます。

1.Firebaseのコンソールで電話番号認証を許可

AuthenticationタブからONにするだけです

これでアプリケーションで使えるようになります

料金体系

Sparkプランは1万/月でいけるので、試しにテストしてみたかったり小規模なサービスではこれで十分かと思います

1万を超過するようなログイン、登録が発生する場合はBlazeプランにあげたほうが確実です。

Blazeプランの場合は従量課金制度で1万を超過した分に対して1件あたりの金額がかかってきます。

料金を確認

2.reCAPTCHAで認証を設定

主に不正行為を防止する目的でこれ設定する必要があります。

例えばよくある画像を選んでロボットではないことを確認するアレです。

//任意の言語を渡すとreCAPTCHAの言語が自動的に変わります
firecase.auth().languageCode = 'jp'

最近ではユーザーの操作を必要としないreCAPTCHAもあるのですが、firebaseはそれもサポートしています

今回はチェックボックスにチェックするいつものreCAPTCHAを使います

<template>
  <div>
    <a
      id="sign-in-button"
      @click="sendMessage()">
      <span>ログイン</span>
    </a>
    <div id="recaptcha-container"/>
  </div>
</template>

<script>
import firebase, { auth } from 'firebase'

export default {
  data () {
    return {
      recaptchaVerifier: null,
      recaptchaWidgetId: null,
      confirmationResult: null,
      verificationCode: null
    }
  },
  mounted () {
    this.recaptchaVerifier = window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
      'size': 'normal',
      'callback': responseToken => {
         // reCAPTCHA solved
       }
    })

    this.recaptchaWidgetId = await this.recaptchaVerifier.render()
  }
}

これでreCAPTCHAのdivがrenderingされます

この recaptchaVerifier は signIn時の引数で利用するので保持しておきます

3.SMSへのコード送信処理

電話番号は国際番号(+81) + 電話番号で入力されたものを利用します

ここでは決め打ちしていますが、本来はinputタグを用意してそこに入力したものをv-modelなどを利用して取得してきます

async sendMessage() {
  // ダッシュボードからホワイトリストにいれてテストすることが可能です
  const phoneNumber = "+818099999999"
  try {
    this.confirmationResult = await firebase.auth().signInWithPhoneNumber(
      phoneNumber, this.recaptchaVerifier) // ここで先ほどのreCAPTCHA認証を利用します
  }
}

問題なく送信された場合はconfirmationResultにverificationIdが返ってくるのでそれをユーザー認証に使います

4.SMSで届いたコードを入力させてログイン

3で実施したcofirmationResultとSMSに送信されたコードを利用して実際にユーザーを認証させます

※htmlにはないですが、認証コード入力欄と確認ボタンみたいなものがある前提です

// verificationCodeはv-modelなどで指定しているユーザーが入力した認証コード
if (this.confirmationResult && this.verificationCode) {
  try {
    const result = await this.confirmationResult.confirm(this.verificationCode)
    const user = result.user // これでユーザーを取得できる
   } catch (e) {
     // 認証コードが間違っている
   }
}

以上で電話番号で認証をとることが可能です