FirebaseのAuthenticationを利用してvue.jsでのログイン認証の動作確認を行います。本文書ではindex.htmlとcdnを使って動作確認を行うので、実用的なログイン認証の実装ではありませんが本文書を読めばFirebase Authenticationの基本を理解することができます。

Firebaseの設定

アカウント登録

Firebaseのユーザアカウントを持っていない人はまずユーザ登録を行う必要があります。Firebaseのユーザアカウントを持っている人は次の”プロジェクトの作成”に進んでください。

Firebaseへのアカウント登録やAuthenticationを使用する際にクレジット情報などを入力する箇所はありません。
fukidashi

ページが開いたら真ん中にある使ってみるボタンをクリックします。

Firebaseトップページ
Firebaseトップページ

ログイン画面が表示されるので、メールアドレスを入力します。次へボタンにいくとパスワードを聞かれるので入力してください。

Googleアカウント情報を入力
Googleアカウント情報を入力

Firebaseへようこそ画面が表示されればアカウント登録は完了です。

ログイン完了
ログイン完了

プロジェクトの作成

Firebaseにログインするとプロジェクトの作成画面が表示されます。”プロジェクトを追加”をクリックしてください。

以前にプロジェクトの作成を行なっている場合は下記のように右側に既存のプロジェクトが表示されます。
fukidashi
プロジェクト作成画面
プロジェクト作成画面

プロジェクト名を入力する画面が表示されるので任意の名前をつけてください。ここではvue.jsのログイン認証の動作確認を行うので、vue-authenticationという名前にしています。

プロジェクトの命名
プロジェクトの命名

Googleアナリティクスを利用するかどうか確認画面が表示されます。デフォルトでは有効にするになっていますが今回Google Analyticsの利用はないので無効にしてプロジェクト作成ボタンをクリックします。

Google Analyticsの設定
Google Analyticsの設定

プロジェクトの作成画面が表示されます。新しいプロジェクトの準備ができましたと表示されたら、続行ボタンをクリックしてください。

プロジェクト作成画面
プロジェクト作成画面

プロジェクトのコンソール画面が表示されます。

コンソール画面
コンソール画面

Authentication(認証)の設定

コンソール画面のAuthenticationユーザの認証と管理をクリックしてください。

コンソール画面
コンソール画面

Authenticationの設定画面が表示されます。画面真ん中の”ログイン方法を設定”ボタンをクリックしてください。

Authenticationの画面
Authenticationの画面

Googleのアカウントだけではなく様々なプロバイダを利用してログイン設定を行うことができます。ここでは一番上のプロバイダのメール/パスワードをクリックしてください。

ログイン方法の選択画面
ログイン方法の選択画面

メールとパスワードを使った認証を有効にするため、有効にするに変更してください。デフォルトでは有効にするが選択されていません。有効にするに変更後、保存ボタンをクリックしてください。

メール/パスワードを使った認証の設定
メール/パスワードを使った認証の設定

メール/パスワードのステータスが有効になっていることが確認できます。

ステータスが有効
ステータスが有効

ウェブアプリの登録

Authenticationをウェブアプリから利用するためには、SDKが必要となります。SDKはアプリを登録することで取得することができます。

下記の赤四角で囲まれた</>をクリックします。

アプリ登録ボタン
アプリ登録ボタン

アプリの名前を入力する画面が表示されるので、任意の名前をつけます。入力後、アプリを登録ボタンをクリックしてください。

アプリの名前を登録
アプリの名前を登録

ウェブアプリで利用するためのSDKの情報が表示されるので、これらの情報をコピーしてファイルに貼り付けます。

下記の情報では動作しないため各自Firebaseでの設定を行い取得してください。
fukidashi
FirebaseのSDKが表示
FirebaseのSDKが表示

ここではindex.htmlを使って動作確認を行うので下記のように貼り付けを行います。


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
 <!-- The core Firebase JS SDK is always required and must be listed first -->
 <script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-auth.js"></script>
</head>
<body>
<h1>ユーザ登録画面</h1>

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "AIzaSyC76lXHmeAAeimabsC0DKm8ZwG9tBS26ds",
    authDomain: "vue-authentification-e4051.firebaseapp.com",
    databaseURL: "https://vue-authentification-e4051.firebaseio.com",
    projectId: "vue-authentification-e4051",
    storageBucket: "vue-authentification-e4051.appspot.com",
    messagingSenderId: "396852998505",
    appId: "1:396854998605:web:2f69512997341e7a390df8"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
</script>   
</body>
</html>
firebase-app.jsだけではなく認証に必要なfirebase-auth.jsも必要です。これがないとfirebase.auth()が利用できません。
fukidashi

ここまででFirebase側での設定は完了でこれからvue.jsの設定を行い認証の動作確認を行なっていきます。

vue.jsの設定

認証用フォームの作成

手元のパソコンでも簡単に動作確認できるようにvue.jsはcdnを使って読み込みます。フォームを作成するためにbootstrapも利用しているためbootstrapもcdnを使います。


<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

入力フォーム部分は下記のように記述します。メールアドレスとemailの入力欄があるシンプルなフォームです。


<div id="app" class="container mt-5">
  <h2>ユーザ登録画面</h2>
  <div class="row">
      <div class="col-sm-8">
          <form @submit.prevent="registerUser">
              <div class="form-group">
                  <label for="email">メールアドレス:</label>
                  <input type="email" class="form-control" id="email" v-model="email">
              </div>
              <div class="form-group">
                <label for="password">パスワード:</label>
                <input type="password" class="form-control" id="password" v-model="password">
              </div>
              <button type="submit" class="btn btn-info">登録</button>
          </form>
      </div>
  </div>
</div>

vue.jsではデータプロパティにemail, passwordを追加し、input要素にはv-modelでemailとpasswordを追加します。

登録ボタンを押すとsubmitFormメソッドが実行されるようにhtml側のformタグにsubmitイベントを追加します。submitイベントではregisterUserメソッドを設定しています。

submitイベントにはpreventを追加し、ボタンをクリックしても画面がリロードしないように設定しています。
fukidashi

const app = new Vue({
  el: '#app',
  data: {
      email: '',
      password: ''
  },
  methods: {
      registerUser(){
        
      }
  }
});

ブラウザで確認すると入力フォームが下記のように表示されます。

入力フォーム
入力フォーム

Firebase Authenticationを利用する

Firebase SDK、vue.jsによるログインフォームが完了したので、これからFirebase Authenticationの設定を行います。

公式ドキュメントの”ウェブサイトでFirebase Authenticationを使ってみる”を参考に設定を行なっていきます。ドキュメントには認証に利用できるメソッドの情報が記述されています。

ユーザを登録する

公式ドキュメントの記載通りユーザの作成はcreateUserWithEmailAndPasswordメソッドを使って行います。

コードのregisterUserメソッドにcreateUserWithEmailAndPasswordメソッドを追加して、引数に入力フォームで入力されたemailとpasswordを渡します。


methods: {
  registerUser(){
    console.log(firebase);
    firebase.auth().createUserWithEmailAndPassword(this.email, this.password).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
    });
  }
}

入力フォームにemailアドレスとパスワードを入力して登録するボタンをクリックします。

メールアドレスとパスワードの入力
メールアドレスとパスワードの入力
登録するボタンを押したあとコンソールにvue.js:634 [Vue warn]: Error in v-on handler: “TypeError: firebase.auth is not a function”のエラーが表示される場合は、firebase-auth.jsの読み込みを忘れている場合があるので確認してください。
fukidashi

登録が正常に行われるとFirebaseのAuthenticationのコンソールにユーザが登録されます。

ユーザの登録完了
ユーザの登録完了

同じメールアドレスを登録しようとするとコンソールには下記のエラーが表示されます。


auth/email-already-in-use
The email address is already in use by another account.

ユーザのログイン状態の変化を確認

ここまでの設定でユーザの登録を行うことができましたが、現在ユーザがログイン状態なのかログアウト状態を知ることができません。ログイン、ログアウト状態の変化を知るためのメソッドonAuthStateChangedが準備されているのでどうのように使用するのか確認しましょう。

onAuthStateChangedメソッドは、ユーザーのログイン状態が変わるたびに呼び出されるメソッドなのでライフサイクルフックmountedに設定します。


mounted(){
  firebase.auth().onAuthStateChanged(function(user) {
    if (user) {
      console.log('login');
    } else {
      console.log('logout');
    }
  });     
}

ユーザがログインすればコンソールにloginと表示され、ログアウトすればコンソールにlogoutと表示されるように設定しています。

ログインフォーム、ログアウトボタンを追加

ユーザがログイン、ログアウトを行うため仕組みがないたので作成していきます。新たにログインフォームとログアウトボタンのhtmlを追加します。


<div id="app" class="container mt-5">

  <button class="btn btn-primary mb-3" @click="logoutUser">ログアウト</button>
  
  <div class="row">
      <div class="col-sm-6">
          <h2>ユーザ登録画面</h2>
          <form @submit.prevent="registerUser">
              <div class="form-group">
                  <label for="email">メールアドレス:</label>
                  <input type="email" class="form-control" id="email" v-model="email">
              </div>
              <div class="form-group">
                <label for="password">パスワード:</label>
                <input type="password" class="form-control" id="password" v-model="password">
              </div>
              <button type="submit" class="btn btn-info">登録する</button>
          </form>
      </div>
      <div class="col-sm-6">
          <h2>ログイン画面</h2>
          <form @submit.prevent="loginUser">
              <div class="form-group">
                  <label for="loginEmail">メールアドレス:</label>
                  <input type="loginEmail" class="form-control" id="loginEmail" v-model="loginEmail">
              </div>
              <div class="form-group">
                <label for="loginPassword">パスワード:</label>
                <input type="password" class="form-control" id="loginPassword" v-model="loginPassword">
              </div>
              <button type="submit" class="btn btn-info">ログインする</button>
          </form>
      </div>
  </div>
</div>

htmlを変更後にブラウザで確認すると下記のように表示されます。

ログインフォームとログアウトボタンを追加
ログインフォームとログアウトボタンを追加

ログアウトボタンにはクリックイベントでlogoutUserメソッド、ログインフォームにはsubmitイベントでloginUserメソッドを設定しています。

vue.jsには、ログインフォーム用にデータプロパティloginEmail, loginPasswordを追加し、logoutUser, loguinUserメソッドの追加を行います。

ログイン、ログアウトについてはfirebase.authにsignOutメソッドとsignInWithEmailAndPasswordメソッドがあるのでそれを利用します。

authenficationで利用できるメソッドについては公式ドキュメントのリファレンスを確認します。
fukidashi

methods: {
  registerUser(){
    firebase.auth().createUserWithEmailAndPassword(this.email, this.password).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log(errorCode);
      console.log(errorMessage);
    });
  },
  logoutUser(){
    firebase.auth().signOut();
  },
  loginUser(){
    firebase.auth().signInWithEmailAndPassword(this.loginEmail, this.loginPassword).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log(errorCode);
      console.log(errorMessage);
    });
  }
},

ログイン、ログアウトの動作確認

ログイン、ログアウトの設定が完了したので動作確認を行います。それぞれの処理が行われるとonAuthStateChangedが呼び出されて、ログイン/ログアウト状態を確認することができます。

ブラウザでページを開くとonAuthStateChangedが実行されデベロッパーツールのコンソールにlogoutが表示されます。

ユーザ登録直後などユーザがログイン状態の場合はloginと表示されます。意図的にlogout状態にして動作確認をしています。
fukidashi

ページを開いたあとにログアウトボタンを押してください。logout状態であれば状態の変化はないので何も表示されません。ログインしている場合は、ログアウトボタンを押すとlogoutとコンソールに表示されます。

ログイン画面に登録したメールアドレスとパスワードを入力してログインするボタンをクリックします。

ログインを行う画面
ログインを行う画面

ログインするとコンソールにはloginと表示されます。ブラウザをリロードしてみましょう。リロードしてもログイン状態を保っているので、ページを開くとloginと表示されます。

ログアウトボタンを押してください。ログアウトを押すとコンソールにlogoutと表示されます。

firebase.authのメソッドを利用することでログイン、ログアウトが行えることがわかりました。

ページ上で現在のログイン状態を確認し、ログイン状態の場合は、登録フォームとログインフォームを非表示にし、ログアウト状態の場合は、ログアウトボタンを非表示にしたいものです。

現在の状態を利用してページ内容を変更

現在のログイン状態をページ上でも確認できるように新たにデータプロパティAutheticatedUserを追加します。

onAuthStateChangedメソッドを利用して、AutheticatedUserの値を変えます。


const app = new Vue({
  el: '#app',
  data: {
      email: '',
      password: '',
      loginEmail: '',
      loginPassword: '',
      authenticatedUser: ''
  },
  // 中略
  mounted(){
    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        console.log('login');
        this.authenticatedUser = true;
      } else {
        console.log('logout');
        this.authenticatedUser = false;
      }
    });     
  }
});

v-ifディレクティブを利用して表示の切り替えを行います。


<button class="btn btn-primary mb-3" @click="logoutUser" v-if="authenticatedUser">ログアウト</button>

<div class="row" v-else>
    <div class="col-sm-6">
        <h2>ユーザ登録画面</h2>
        <form @submit.prevent="registerUser">
            <div class="form-group">
                <label for="email">メールアドレス:</label>
                <input type="email" class="form-control" id="email" v-model="email">
            </div>

設定が完了したらv-ifディレクティブの動作確認を行います。

logoutの状態でアクセスすると登録画面とログイン画面が表示されます。ログインフォームにメールアドレスとパスワードを入力してログインするボタンを押します。

ログインを行う
ログインを行う

ログインが完了するとv-ifディレクティブにより、ログアウトボタンのみの表示となります。

ログイン状態
ログイン状態

ログアウトボタンを押すとログアウトボタンが消えて入力フォームが表示されます。

ログインフォームが表示
ログインフォームが表示

input要素に入力した内容が表示されているのはログイン完了後にloginEmailとloginPasswordをそのままにしているためです。ログイン完了後に下記の処理を追加すればログイン完了後に入力したメールアドレスとパスワードは消えます。


loginUser(){
  firebase.auth().signInWithEmailAndPassword(this.loginEmail, this.loginPassword)
    .then(()=>{
      this.loginEmail = '';
      this.loginPassword = '';
    })
    .catch(function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    console.log(errorCode);
    console.log(errorMessage);
  });
}

ルーティングによるページの遷移のないindex.htmlファイルのみで認証の動作確認を行いましたが、firebase.authで使用できるメソッドも確認することができたので、Firebase Authenticationを使う上で基本となる知識は得られたかと思います。