ログイン

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

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

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

AuthenticationでSMSログイン

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

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

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

Firebaseへメールアドレス認証Twitter認証Facebook認証Google認証匿名認証、お次はGitHubです。

AuthenticationでGitHubログイン

エンジニア向けのサイトだとGitHubでログインさせたくなりますよね。

Firebase Webコンソールの設定

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

画面の真ん中あたりにある「GitHub」のアコーディオンメニューを開き、「有効にする」にチェックしたあと、コールバックAPIをメモします。

ここまで出来たらGitHubへ移動します。

続きを読む

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

Firebaseへメールアドレス認証Twitter認証匿名認証と続き、今回はfacebookでの認証に挑戦します。

Authenticationでfacebookログイン

Facebookアプリを作成する際に、実際に本番で利用するためには「プライバシーポリシー」が掲載されたURLが必要になります。開発段階では不要ですが公開を考えている場合には早めに用意しておくことをおすすめします。

facebookでデベロッパー登録

Facebookにログインし、開発者サイトから登録を行います。

登録する手順も書こうと思ったのですが、10年以上前に登録を終えてしまっていたためここでは割愛します。FacebookはTwitterと違って複数のアカウントが作れない(作りづらい)のですよね(´・ω・`)

facebookアプリを作成

開発者サイトの右上のメニュー「マイアプリ」→「新しいアプリを追加する」をクリック

アプリの名称とメールアドレスを入力し「アプリIDを作成してください」をクリック

続きを読む

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

以前はFirebaseへメールアドレスでのログインを行いましたが、今回はTwitterでの認証に挑戦したいと思います。

AuthenticationでTwitterログイン

Twitterでアプリを作成

まず最初にTwitterでデベロッパー登録を行う必要があります。承認されるまでに数時間〜数日かかりますので思いついたら早めに申請しておくのがおすすめです。

その後Twitter上でOAuthアプリを作成します。といっても何も難しいことはなく必要な項目をフォームに入力するだけです。このときにCallback URLの入力を求められたら、いったんFirebseのWebコンソールへ移動します。

Twitterのデベロッパーサイトは日本語訳されていませんので、私もそうなのですが英語が苦手な方はGoogle翻訳をタブで開きながら行えばなんとかなります。
続きを読む

[Firebase] Authenticationでメール認証 (Web編) その3

第1回はメールアドレスとパスワードによる認証、第2回はメールアドレス宛にメールを送信し文中のURLをクリックするとログイン状態になる機能の実装に挑戦しました。

今回は次のような仕組みに挑戦してみます。

  1. メールアドレスとパスワードを入力しログイン
  2. ログイン後、メールアドレスの認証が終わってなければ確認メール送信
  3. 確認メール内にあるURLをクリックするとメールアドレスの認証完了

メールアドレスの確認

コンソールの設定

第1回で行った、以下の設定が必要です。「Authentication」から「ログイン方法」タブに移動し「メール/パスワード」を有効にしてください。

JSで認証処理

/js/config.js

共通処理を書いておくJSです。
第2回と全く同じです。

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

//----------------------------------------------
// ドメインとポート番号
//----------------------------------------------
let domain = document.domain;
let port   = (domain === 'localhost')?  5000:80;

/auth/mail2/index.html

ユーザーが最初にアクセスするログイン画面です。
こちらは第1回で使用した設定用JSONに戻しました。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</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>Hello Firebase Auth</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/mail2/done.html',

        // 利用する認証機能
        signInOptions: [
          firebase.auth.EmailAuthProvider.PROVIDER_ID  //メール認証
        ],

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

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

/auth/mail2/done.html

今回の話のメインはこちらですね。
ログイン時に渡されるオブジェクトのuser.emailVerifiedfalseであればまだメールアドレスの確認が行われていないことになります。その場合にuser.sendEmailVerification()メソッドを使用し、メールアドレス宛に確認メールを送信しています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</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) => {
      console.log(user);

      //------------------------------------
      // 未ログイン状態で訪れた場合
      //------------------------------------
      if(user === null){
        showMessage('Not Login', 'ログインが必要な画面です');
        return(false);
      }

      //------------------------------------
      // メアド確認済み
      //------------------------------------
      if( user.emailVerified ) {
        showMessage('Login Complete!', `${user.displayName}さんがログインしました`);
      }
      //------------------------------------
      // メアド未確認
      //------------------------------------
      else {
        user.sendEmailVerification()
          .then(()=>{
            showMessage('Send confirm mail', `${user.email}宛に確認メールを送信しました`);
          })
          .catch((error)=>{
            showMessage('[Error] Can not send mail', `${user.email}宛に確認メールを送信できませんでした: ${error}`);
          });
      }
    });

    function showMessage(title, msg) {
      document.querySelector('h1').innerText    = title;
      document.querySelector('#info').innerHTML = msg;
    }
  </script>
</body>
</html>

実行結果

クリックするとサンプルコードが実行できます。お試し登録やログインなどどうぞ。自分以外のメアドを入れたり悪いことしないでくださいね。(登録された内容は適当なタイミングで削除します)

done.htmlで送信されたメール内のURLをクリックすると、デフォルトで用意されているメールアドレスの確認ページが表示され、user.emailVerifiedの値がそれ以降trueに変化します。もう一度ログインを行うと今度は確認メールが送信されず、ログインが完了した旨が表示されれば成功です。

その他

メールの文面を変更する

デフォルトの確認メールの文面は中々怪しさに溢れているので、Web画面の開発が一段落したらこちらの文面も差し替えた方が良いでしょう。

コンソールの「Authentication」から「テンプレート」タブにアクセスするとカスタマイズができます。

確認ページから遷移させる

メール内のURLをクリックすると以下のような簡単な画面が表示されます。
これだけだと次のアクションをどうすればよいかユーザーが混乱しますので、実際には次のページへ遷移するためのボタンなどを置いた方がユーザーフレンドリーです。

というわけで、done.htmlのコードを修正しました。
sendEmailVerification()に引数として設定用のJSONを渡しています。変数domainportの値はconfig.jsで作成しています。

  actionCodeSettings = {
    url: `http://${domain}:${port}/auth/mail2/done.html`
  };
  user.sendEmailVerification(actionCodeSettings)

このコードを実行すると、今度は以下のように「続行」ボタンが表示されましたね。

なおここで指定するURLのドメインはホワイトリストに登録されている必要があるのでご注意を。
コンソールにログインしたら「Authentication」内の「ログイン方法」タブをクリックし「承認済みドメイン」の項目の右側にある「ドメインの追加」ボタンから設定します。

参考ページ


[Firebase] Authenticationでメール認証 (Web編) その2

前回はメールアドレスとパスワードによる認証でしたが、今回は入力されたメールアドレスにメールを送信し届いたURLをクリックしたらログイン状態になる「メールリンク認証」の実装をします。

メールリンク認証

入力されたメールアドレス宛に確認メールを送り、中のURLをクリックしてログイン状態となるこの仕組をFirebaseでは「メールリンク認証」という言葉を用います。メールリンク認証ではパスワードも求められません。

コンソール上の設定

「Authentication」の「ログイン方法」内にある「メール / パスワード」の項目を開き、「メールリンク」を有効にするにし、保存ボタンをクリックします。

認証部分をJSで書く

/js/config.js

ドメインとポート番号の設定を加えましたが、前回と一緒です。

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

//----------------------------------------------
// ドメインとポート番号
//----------------------------------------------
let domain = document.domain;
let port   = (domain === 'localhost')?  5000:80;

/auth/mail/index.html

メインはこちらですが、JSONの値を変更しただけですねw forceSameDeviceはメールソフトのURLをクリックした際に同じデバイスであることを要求するかどうかのフラグです。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</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>Hello Firebase Auth</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/mail/done.html',

        // 利用する認証機能
        signInOptions: [
          {
            provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
            signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD,
            forceSameDevice: false
          }
        ],

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

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

/auth/mail/done.html

前回とほぼ一緒です。変更点としてはdisplayNameの他にemailemailVerifiedの表示を行っています。今回はユーザー名の入力が入らないためdisplayNameには何も入りません。メールアドレスの認証が完了しているアカウントの場合emailVerifiedtrueになります。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Firebase Auth</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.displayName}さんがログインしました`
                         + '<ul>'
                         +   `<li>${user.email}</li>`
                         +   `<li>${user.emailVerified}</li>`
                         + '<ul>';
        console.log(user);
      }
      else {
        h1.innerText = 'Not Login';
      }
    });
  </script>
</body>
</html>

実行結果

クリックするとサンプルコードが実行できます。お試しに登録やログインなどどうぞ。自分以外のメアドを入れたり悪いことしないでくださいね。(登録された内容は適当なタイミングで削除します)


※今回からAWSではなくFirebase Hostingに置くことにしました

この認証方法だと毎回メールを受信してクリックして…というフローをたどるため面倒ですが、確実にメールアドレスの存在確認ができるという点では良い方法かと思います。あとはdisplayNameがほしい場合は自分で入力フォームを作成して、プロフィールの更新用APIを呼び出す形になるかと思います。

その他

独自ドメインで利用する

Firebase Hostingデフォルトのfoo.firebaseapp.comlocalhostで利用するのであれば特に設定はいらないのですが、独自ドメインで認証を行う場合はホワイトリストにドメインを設定しておく必要があります。「Authentication」内の「ログイン方法」タブをクリックし「承認済みドメイン」の項目の右側にある「ドメインの追加」ボタンから設定します。

この設定をしないとDomain not whitelisted by projectというエラーメッセージが表示され、確認メールを送信する処理が実行されません。

メールのテンプレートを変更する?

デフォルトだと以下のようなメールが届くのですがさすがに分かりづらいですね…。怪しさ満点です。

が、執筆時点でこのテンプレートの変更がコンソールを見ても見当たらないんですよね…。その他のパスワード変更やメールアドレスの存在確認用のテンプレはあるのですが。どなたかお分かりになる方がいらっしゃったら教えていただけると!

後日判明したら追記したいと思います。

続き

参考ページ

[Firebase] Authenticationでメール認証 (Web編) その1

Firebaseの機能を順次試していきたいと思います。
FirebaseではAuthenticationを利用することで様々な認証を用いることができます。今回実装するメールアドレスの他に各種SNSやSMSなどにも対応可能です。Webの他にiOSやAndroidなどにも導入可能。

今回は単純なログイン機能をWebページに実装してみます。
メールアドレスとパスワードを入力すると登録やログインできるようになります。

Authenticationでログイン

コンソール上の設定

Firebaseのコンソールにログインし、新しくプロジェクトを作成するか、既存のプロジェクトを選択します。

プロジェクトのダッシュボードに移動したら、早速Authenticationの設定を進めていきます。
まずは左側のメニューの「Authentication」をクリックし、右ペインが切り替わったら「ログイン方法」タブをクリック。

「メール/パスワード」の行をクリックし、「有効にする」のスライダーをクリック。
その後「保存」ボタンをクリック。

この後JSを書き始めるのですが、その前にプロジェクトの情報を取得します。プロジェクトのコンソール右上にある「ウェブ設定」ボタンをクリック。

JSの設定部分の雛形が表示されますので、これをコピーします。

これでブラウザでのFirebaseの必須の設定はひとまずこれで完了です。
簡単でしたねw

認証処理をJSで書く

今回は認証部部のUIがまるっとセットになったfirebaseui-webを使っていきます。

ここでは次の3つのファイルを作成しています。

config.js
前項でコピペしたコンソールの内容を保存します。
login.html
ログイン画面のHTML
done.html
ログイン完了画面のHTML

続きを読む