[Firebase] AuthenticationでSMS認証 (Web編)

これまでFirebaseへ様々な認証をお試してしてきました。

今回は電話番号を使ったSMS認証です。

AuthenticationでSMSログイン

メールアドレスやSMSは匿名性の高い物が一人で量産できてしまいますが、電話番号であれば何かしらの契約が必要になりますのでハードルを高くすることが可能です。

この認証方法ではユーザーが入力した電話番号宛にFirebaseからSMS(昔でいうショートメール)が送信されます。SMS内にある暗証番号をログインページで入力してもらうことで本人確認が行えるというわけです。

Firebase Webコンソールの設定

FirebaseのWebコンソールへログインしたら、メニュー「Authentication」→「ログイン方法」とたどります。

画面の真ん中あたりにある「電話番号」のアコーディオンメニューを開き「保存」ボタンをクリックするだけです。

ソースコード

config.js

いつものやつです。FirebaseのWebコンソールに表示されたものをそのままコピペします。

// コンソールの内容をそのままコピペ
var config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "test-f76bc.firebaseapp.com",
  databaseURL: "https://test-f76bc.firebaseio.com",
  projectId: "test-f76bc",
  storageBucket: "test-f76bc.appspot.com",
  messagingSenderId: "0000000000000"
};
firebase.initializeApp(config);

index.html

FirebaseUIを利用します。TwitterやFacebookの時と同様にsignInOptionsfirebase.auth.PhoneAuthProvider.PROVIDER_IDを指定します。この他にオプションについては後述します。

電話番号の入力方法ですが、国際電話のかけ方と同じで、電話番号が 090-1234-5678 であれば最初のプリフィクスであるゼロは省略し 9012345678と入力します。ユーザーに不慣れた方が想定される場合は注意書きをしておいたほうが良いかもですね。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Firebase Auth for Phonenumber</title>
  <link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
  <style>h1{text-align: center;}</style>
</head>
<body>
  <h1>Firebase Auth for Phonenumber</h1>
  <div id="firebaseui-auth-container"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/ui/3.5.2/firebase-ui-auth__ja.js"></script>
  <script src="/js/config.js"></script>
  <script>
    //----------------------------------------------
    // Firebase UIの設定
    //----------------------------------------------
    var uiConfig = {
        // ログイン完了時のリダイレクト先
        signInSuccessUrl: '/auth/sms/done.html',

        // 利用する認証機能
        signInOptions: [{
          provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
          defaultCountry: 'JP',
          //whitelistedCountries: ['JP', '+81']
        }],

        // 利用規約のURL(任意で設定)
        tosUrl: 'http://example.com/kiyaku/',
        // プライバシーポリシーのURL(任意で設定)
        privacyPolicyUrl: 'https://miku3.net/privacy.html'
      };

      var ui = new firebaseui.auth.AuthUI(firebase.auth());
      ui.start('#firebaseui-auth-container', uiConfig);
  </script>
</body>
</html>

done.html

ログイン完了時に表示される画面です。SMSによる認証はそのままだとユーザー名が取れないようなので、ここでは電話番号(phoneNumber)を表示しています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Firebase Auth for Phonenumber</title>
</head>
<body>
  <h1>...Please wait</h1>
  <div id="info"></div>

  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.8.1/firebase-auth.js"></script>
  <script src="/js/config.js"></script>
  <script>
    firebase.auth().onAuthStateChanged( (user) => {
      let h1   = document.querySelector('h1');
      let info = document.querySelector('#info');

      if(user) {
        h1.innerText   = 'Login Complete!';
        info.innerHTML = `${user.phoneNumber}さんがログインしました<br>` +
                         `(${user.uid})`;
        console.log(user);
      }
      else {
        h1.innerText = 'Not Login';
      }
    });
  </script>
</body>
</html>

実行結果

SMSでのログインを試すことができます。 miku3.net

実際に操作すると以下のようなSMSが到着します。この6桁の数字をログインページに入力してやります。SMSはネットワークの状況によってすぐに到着することもあれば、少しラグがあることもあります。数分程度は待ったほうが良いでしょう。

FirebaseのWebコンソールからは以下の通り確認できます。

解説

最初に選択される国を指定する

デフォルトだと以下のようにアメリカが選択された状態になりますが、日本向けのサービスであれば初期選択値は日本にしておきたいですよね。

そんなときに利用するのがdefaultCountryオプションです。ここで国コードを指定すればデフォルトで選択された状態になります。

    var uiConfig = {
        signInOptions: [{
          provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
          defaultCountry: 'JP',
        }],

特定の国のみ選択させたい

日本以外は選択させたくない、そんなときにはwhitelistedCountriesオプションを使用します。国番号または国コードを入力します。

    var uiConfig = {
        signInOptions: [{
          provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
          defaultCountry: 'JP',
          whitelistedCountries: ['JP', '+81']
        }],

参考ページ

firebase.google.com github.com