vue.jsとFirebaseのRealtime DatabaseとAuthorization機能を利用したSlackクローンの構築を複数回にわけて行っています。3回目となる今回は前回作成したユーザ登録画面とサインイン画面に認証機能の追加を行います。ユーザ管理と認証はFirebaseの機能を利用して行います。認証機能についてはSlackに限定することなく他のアプリケーションを利用する際にも利用することができます。

本文書を読みすすめる前に下記の文書を確認することをおすすめします。

サインイン後の画面の作成

Home.Vueファイルにサインイン後の画面を作成します。この画面内でSlack Cloneのメッセージの送受信を行いますがが現段階ではその機能は実装されていないので下記のコードのみ記述しておきます。


<template>
  <div>
    <h1>Slack Clone</h1>
    <p>ログイン中</p>
    <div>
      <button class="py-1 px-4 bg-gray-800 text-white rounded">サインアウト</button>
    </div>
  </div>
</template>

認証の設定を通してユーザのサインインが完了した場合のみこの画面が表示されるように設定を行っていきます。現時点では認証によるアクセスの制限を行っていないため/(ルート)にアクセスすると下記の画面が表示されます。

サインイン後の画面
サインイン後の画面

FirebaseのAuthentication(認証)の設定

Firebase上で認証設定を行っていきます。認証設定を行うとFirebase上でユーザの登録と管理を行うことができます。

Firebaseにログイン、コンソールからAuthentication(ユーザーの認証と管理)をクリックします。

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

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

Authetication画面
Authetication画面

認証に利用することができる方法一覧が表示されます。GoogleやTwitterのアカウントを利用することができますが、ここでは一番上のメール/パスワードを利用するのでメール/パスワードをクリックしてください。

ログイン方法の一覧
ログイン方法の一覧

メール/パスワードをクリックすると有効化を選択する画面が表示されるので、現在無効になっている一番上のボタンをクリックして有効にしてください。

メールアドレス/パスワードの設定画面
メールアドレス/パスワードの設定画面

有効化にした後の画面は下記となります。有効化した後は右下の保存ボタンをクリックしてください。

有効化後の画面
有効化後の画面

再度認証方法の一覧画面が表示されるのでメール/パスワードのステータス列が有効になっていることを確認してください。

認証一覧でメール/パスワードのステータス
認証一覧でメール/パスワードのステータス

有効化の設定が完了したのでメール/パスワードを利用してFirebaseへのユーザの登録を行うことが可能となりました。Authnticationのタイトルの下にあるタブの中から一番左にあるUsersタブをクリックしてください。

ユーザは登録されていないので”このプロジェクトには、まだユーザがいません”と表示されます。

認証ユーザが存在しない
認証ユーザが存在しない

Firebaseでのユーザの認証設定が完了したのでここからVue.jsを使ってFirebaseへのユーザ登録の機能を追加していきます。

ユーザの登録設定

Firebaseでの認証に関する初期設定が完了したのでvue.js上でユーザの登録設定を行っています。ユーザ登録画面は前回の公開済文書の中で作成は完了しているのでコンポーネントファイルにvue.jsのコードを追加していきます。

データプロパティの追加

ユーザの登録にはEmailとパスワードを利用して行います。そのためRegister.vueファイルにデータプロパティのemailとpasswordを追加します。


<script>
export default {
  data() {
    return {
      email: "",
      password: ""
    };
  }
};
</script>

追加したemailとpasswordをinput要素にバインドするためにv-modelを設定します。


<form>
  <div class="mb-2">
    <input
      type="email"
      v-model="email"   //追加
      placeholder="you@example.com"
      class="text-xl w-3/5 p-3 border rounded"
    />
  </div>
  <div class="mb-2">
    <input
      type="password"
      v-model="password" //追加
      class="text-xl w-3/5 p-3 border rounded"
      placeholder="パスワード"
    />
  </div>
  <button
    type="submit"
    class="text-xl w-3/5 bg-green-800 text-white py-2 rounded"
  >ユーザの登録</button>
</form>

メソッドの追加

入力フォームに入力した文字をvue.js側で取得するためにformタグにsubmitイベントを追加しregisterUserメソッドを設定します。submitイベントに設定することでユーザ登録ボタンをクリックするとregisterUserメソッドを実行することができます。


<form @submit.prevent="registerUser">
@submitイベントにpreventをつけることでsubmitによりページのリロードが行われるデフォルト動作をキャンセルすることができます。つまりsubmitを実行してもページのリロードは行われません。

vue.jsにregisterUserメソッドを追加します。動作確認にするためinputに入力した値をコンソールログに表示させます。


<script>
export default {
  data() {
    return {
      email: "",
      password: ""
    };
  },
  methods: {
    registerUser() {
      console.log(this.email, this.password);
    }
  }
};

動作確認を行うため/registerにアクセスしてメールアドレスとパスワードを入力してユーザの登録ボタンをクリックしてください。

ユーザ登録画面
ユーザ登録画面

ブラウザのデベロッパーツールのコンソールに入力したメールアドレスとパスワードが表示されることを確認してください。ここではjohn@example.comとパスワードにはpasswordを入力しました。


john@example.com password

Firebaseへのユーザの登録

registerUserメソッドで入力したemailとpasswordが取得できることがわかったのでFirebaseへのユーザ登録を行います。

Firebaseにユーザを登録するためにはライブラリが必要となりますがfirebaseのライブラリはインストール済みなのでFirebaseのユーザ登録に必要なライブラリのimportを行います。


<script>
import firebase from "firebase/app";
import "firebase/auth";

export default {

ユーザを登録するためのfirebaseのメソッドはcreateUserWithEmailAndPasswordです。引数にメールアドレスとパスワードをとるため、registerUserメソッドで取得したemailとパスワードを引数に指定します。


import firebase from "firebase/app";
import "firebase/auth";

export default {
  data() {
    return {
      email: "",
      password: ""
    };
  },
  methods: {
    registerUser() {
      firebase
        .auth()
        .createUserWithEmailAndPassword(this.email, this.password)
        .then(response => {
          console.log(response);
        })
        .catch(e => {
          console.log(e);
        });
    }
  }
};

設定が完了したらユーザ登録画面からユーザ登録を行います。ユーザ登録ボタンを押しても画面には何も変化はありませんが、デベロッパーツールのコンソールにはFirebaseからのresponseが表示されます。

ユーザ登録画面
ユーザ登録画面

ユーザの登録ボタンを押した後Firebaseのコンソールからユーザが登録されているか確認を行います。以下のようにjohn@example.comのユーザが追加されていることが確認できたらユーザ登録の機能は正常に動作しています。たった数行だけでユーザの登録を行うことができました。

ユーザの登録
ユーザの登録の確認

アクセス制限設定

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

ユーザが登録できることはわかりましたがアクセスの制限を行うためには、ユーザがFirebaseへログインが行われているのかどうかを確認する仕組みが必要になります。

Firebaseではログインが完了しているかどうかはonAuthStateChangedメソッドを利用して行うことができます。下記のコードを追加することでuserの値を持てばサインインは行われており、持たなければサインインはおこなわれていません。


firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // ユーザがサインインしている
  } else {
    // ユーザがサインインしていない
  }
});

アクセスの制限設定

/(ルート)へのアクセスはサインインしているユーザのみ許可をさせたいのでRouterのナビゲーションガードbeforeEnterを利用します。ユーザがサインインしている状態確認をnAuthStateChangedメソッドで行い、サインインしている場合のみアクセスできるように設定を行います。

routerディレクトリのindex.jsファイルを開いてfirebaseのライブラリをimportします。


import firebase from "firebase/app";
import "firebase/auth";

/(ルート)へのルーティングにbeforeEnterを追加し、onAuthStateChangedでサインしていることが確認できたらそのままアクセスを許可し、サインインしていない場合はサインイン画面にリダイレクトするように設定を行います。


const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    beforeEnter: (to, from, next) => {
      firebase.auth().onAuthStateChanged(user => {
        if (user) {
          console.log(user)
          next()
        } else {
          next("/signin");
        }
      });
    }
  },

ユーザ登録直後の状態はサインインしている状態なので/(ルート)にアクセスするとHome.vueファイルの中身である下記の画面が表示されます。

サインイン後の画面
ユーザ登録にアクセスした場合

本当にサインインしているユーザだけがアクセス可能なのかどうかはわからないのでサインアウトの機能を追加して動作確認を行います。

サインアウト設定

Home.vueファイルにサインアウトのボタンを作成済みなのでボタンにclickイベントを追加します。clickイベントに追加するメソッドはsignOutです。


 <button class="py-1 px-4 bg-gray-800 text-white rounded" @click="signOut">サインアウト</button>

サインインしているユーザをサインアウトするFirbaseのメソッドはfirebase.auth().signOut()です。Home.vueにsignOutメソッドを追加します。


<script>
import firebase from "firebase/app";
import "firebase/auth";

export default {
  methods: {
    signOut() {
      firebase.auth().signOut();
      this.$router.push("/signin");
    }
  }
};
</script>
this.$router.push(‘home’)はRouterの機能で指定したパスにリダイレクトすることができます。

追加後サインアウトボタンをクリックしてください。サインアウトボタンを押すと自動で/signinにリダイレクトします。

サインイン後の画面
サインイン後の画面

サインアウト後に再度/(ルート)にアクセスするとRouterのbeforeEnterで追加した設定により強制的に/signin画面にリダイレクトされます。アクセス制限ができていることが確認できます。

サインイン画面
サインイン画面

サインイン画面が表示されますが、サインインの設定を行っていないため先程登録したユーザのメールアドレスとパスワードを入力してサインインボタンを押して何も反応はありません。次はサインインの機能追加を行います。

サインインの設定

ユーザ登録したメールアドレスとパスワードを使ってサインインできるように設定を行っていきます。

データプロパティの追加

ユーザのサインインにはユーザ登録と同様にEmailとパスワードを利用します。そのためSignIn.vueファイルにデータプロパティのemailとpasswordを追加します。


<script>
export default {
  data() {
    return {
      email: "",
      password: ""
    };
  }
};
</script>

追加したemailとpasswordをinput要素にバインドするためにv-modelを設定します。


<form>
  <div class="mb-2">
    <input
      type="email"
      v-model="email"
      placeholder="you@example.com"
      class="text-xl w-3/5 p-3 border rounded"
    />
  </div>
  <div class="mb-2">
    <input
      type="password"
      v-model="password"
      class="text-xl w-3/5 p-3 border rounded"
      placeholder="パスワード"
    />
  </div>
  <button type="submit" class="text-xl w-3/5 bg-green-800 text-white py-2 rounded">サインイン</button>
</form>

サインインメソッドの追加

サインインではformタグにSignInメソッドを追加します。


<form @submit.prevent="signIn">

vue.jsにsignInメソッドを追加します。signInメソッドの中ではfirebaseのsignInWithEmailAndPasswordメソッドを利用します。

signInWithEmailAndPasswordメソッドの引数はメールアドレスとパスワードを取ります。サインインが完了すると/(ルート)に移動するように設定を行っています。メールアドレス、パスワードに誤りがある場合はコンソールログにエラーメッセージが表示されます。


import firebase from "firebase/app";
import "firebase/auth";

export default {
  data() {
    return {
      email: "",
      password: ""
    };
  },
  methods: {
    signIn() {
      firebase
        .auth()
        .signInWithEmailAndPassword(this.email, this.password)
        .then(response => {
          console.log(response);
          this.$router.push("/");
        })
        .catch(e => {
          console.log(e);
        });
    }
  }
};

ユーザ登録したメールアドレスとパスワードを入力してサインインボタンを押します。

サインイン画面
サインイン画面

メールアドレスとパスワードに誤りがない場合は、自動で/(ルート)にリダイレクトします。

サインイン後の画面
サインイン後の画面

もしメールアドレスに間違いがあった場合はコンソールに以下のメッセージが表示されます。メールが存在しないのでエラーにはuser-not-foundを確認することができます。


u {code: "auth/user-not-found", message: "There is no user record corresponding to this identifier. The user may have been deleted.", a: null}

ここまでの設定でサインインしたユーザのみ/(ルート)へのアクセスが可能になりFirebaseの認証機能を利用した設定は完了です。

ユーザ認証の設定が完了したので次はSlack Cloneのメインパートであるメッセージ送信の画面作成、実装を行っていきます。