【Vue.js】Vue.js(Nuxt.js)でユーザー登録・ログイン・ログアウトなどの認証機能を簡単に実装する with Firebase【Firebase Auth】
今回はVue.jsで作成するアプリケーションに認証機能を実装します。
Firebase Authenticationを使いますので、手間なく速攻で実装が可能です。
今回はNuxt.jsを使っています。Nuxt.jsの環境が整っていない方は以下のページを参照して下さい。
目次
Firebase側の設定
まずはFirebaseコンソールにアクセスします。
https://console.firebase.google.com/
この画面から「プロジェクトを追加」を選択し、プロジェクト名などを入力してプロジェクトを作成します。
作成したプロジェクト内に入ったら、ご自分の作成対象アプリケーション(iOS、Android、Web)に合わせてconfigなどを取得します。
今回はWEBを例にします。
対象を選ぶと、config情報などが表示されますのでコピーしましょう。
内容は以下の通りです。ユーザーごとに書かれている内容(ドメインなど)が異なりますので必ずご自分の環境で表示されたconfigを使用しましょう。
<script src="https://www.gstatic.com/firebasejs/5.7.0/firebase.js"></script> <script> // Initialize Firebase var config = { apiKey: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", authDomain: "xxxxxxxx.firebaseapp.com", databaseURL: "https://xxxxxxxx.firebaseio.com", projectId: "xxxxxxxx", storageBucket: "xxxxxxxx.appspot.com", messagingSenderId: "1111111111111111111" }; firebase.initializeApp(config); </script>
最後に、認証機能を設定します。
認証の設定画面に移動し、ログイン方法を指定します。
今回はメールアドレスとパスワードを使った一般的なログイン方法を使います。
「メール/パスワード」の項目をクリックして、設定を有効にします。
有効にしたら保存を忘れずに。
もちろんここで、SNS認証の設定もできますが、今回はやりません。
後日やることがあれば追記したいと思います。
Firebaseを使うためにNuxt.js側で設定
上記でコピーしたconfigの内容をNuxt.jsに反映して行きます。
コピーした内容の1行目にある
<script src="https://www.gstatic.com/firebasejs/5.7.0/firebase.js"></script>
は、二通りの方法で導入が可能です。
yarnでfirebaseモジュールを組み込む方法
こちらが一般的ですね。
$ yarn add firebase --save
これを実行すれば、Nuxt.js上では以下のようにfirebaseを呼び出すことが可能になります。
// firebaseのインポート import firebase from 'firebase'
nuxt.config.jsで読み込む
動作確認はしていないですが、こちらの方法でも可能だと思います。
Nuxt.jsは外部リソースを読み込む際にnuxt.config.jsに定義が必要です。
今回のfirebaseのスクリプトであれば以下のようになります。
module.exports = { head: { script: [ { src: 'https://www.gstatic.com/firebasejs/5.7.0/firebase.js' } ] } }
これでfirebaseを使う環境は整いました。
早速画面を作成して行きましょう。
認証画面の作成
Nuxt.jsの場合はページの作成には、pagesディレクトリ配下にvueファイルを追加して行きます。
http://www.sky-limit-future.com/entry/nuxtjs_vue_router
今回は全て同じ画面でやるとして、authページを作成します。
もちろん新規登録画面・ログイン画面などを分けてもOKです。
/pages
├ index.vue
└ auth.vue
auth.vue
スタイルは省略しています。
<template> <section class="container"> <div> <h1 class="title"> firebaseでログイン実装しました! </h1> <section class="ex__box"> <h5>新規登録</h5> <p><input type="text" v-model="mailAddress" placeholder="メールアドレス"></p> <p><input type="password" v-model="password" placeholder="パスワード"></p> <div class="links"> <a class="button--green">新規登録</a> </div> </section> <section class="ex__box" > <h5>ログイン</h5> <p><input type="text" v-model="mailAddress" placeholder="メールアドレス"></p> <p><input type="password" v-model="password" placeholder="パスワード"></p> <div class="links"> <a class="button--green">ログイン</a> </div> </section> <section class="ex__box"> <h5>ログイン中です</h5> <div class="links"> <a class="button--grey">ログアウト</a> </div> </section> </div> </section> </template> <script> export default { data: function(){ return { mailAddress: '', password: '', } }, methods: { }, } </script>
今回はクライアント側でのエラーハンドリングなどは省略していますが、本来であれば入力形式のチェックなどはやるべきでしょう。
Firebase Authenticationからエラーが返却されてきた場合だけエラーを出すように実装していこうと思います。
dataとして、メールアドレス、パスワードを用意しています。
ここまでで画面を作成完了です。
続いてFirebase Authenticationとの連携部分を作成しましょう。
Firebase Authenticationとの連携
今回はこのようなイメージで作成して行きます。
Firebase Authenticationとの接続はapiディレクトリ配下のUserAPI.jsで行います。
これは私の好みなので、apiディレクトリなしで、次に説明するモジュール内から直接呼ぶ実装でも問題ないと思います。
/api
└ UserAPI.js
Vuexを使って状態管理を行うので、ユーザー情報を管理するためにuserモジュールを作成します。
Nuxt.jsではstoreディレクトリの配下に「*.js」のファイルを作成するとそれがモジュールとして認識されるので、今回はuser.jsを作成します。
/store
└ user.js
最後に、先ほど作成したauth.vueで制御を行います。
まずは接続部分を作成します。
UserAPI.jsの作成
apiディレクトリを作り、その配下にUserAPI.jsを作成します。
今回必要な機能は以下の通りです。
・新規ユーザー登録
・ログイン
・ログアウト
・ユーザー情報取得
// firebaseのインポート import firebase from 'firebase' export default class UserAPI { /** * メールアドレスとパスワードで新規ユーザー登録を実施します。 * @param {string} mailAddress * @param {string} password */ static regist(mailAddress, password) { return firebase.auth().createUserWithEmailAndPassword(mailAddress, password); } /** * メールアドレスとパスワードでログインを実施します。 * @param {string} mailAddress * @param {string} password */ static login(mailAddress, password) { return firebase.auth().signInWithEmailAndPassword(mailAddress, password); } /** * ログアウトします。 */ static logout(){ return firebase.auth().signOut(); } /** * ユーザー情報を取得します。 */ static getUser(){ return firebase.auth().currentUser; } /** * ユーザー情報を取得します。 */ static authStateCheck(){ return firebase.auth().onAuthStateChanged(); } }
ユーザー情報の取得に関しては、currentUserとonAuthStateChangedを用意しましたが、ドキュメントを見るとonAuthStateChangedが推奨されているようです。
ここに関しては研究中ですので、とりあえず2つ用意しており、前者を主に使用しています。
userモジュールの作成
storeディレクトリ内にuser.jsを作成して、以下のようにします。
少し長いので分割して解説します。
まずはapiのインポートとstateの定義です。
// UserAPIのインポート import UserAPI from "../api/UserAPI" export const state= () => ({ isLogin : false, emailAddress : "", authError: "" })
今回は3つ用意しています。
isLogin : ログイン状態かを判定
emailAddress : メールアドレス
authError : 認証エラー時のメッセージ
次にミューテーションです。
export const mutations = { // ユーザー情報を設定します。 setEntity (state, user) { state.emailAddress = user.email; }, // stateを初期化します。 clear (state) { state.emailAddress = ""; state.isLogin = false; state.authError = ""; }, // エラーメッセージを設定します。 setAuthError (state, authError) { state.authError = authError; }, // ログイン状態を設定します。 setIsLogin (state, isLogin) { state.isLogin = isLogin; } }
setEntityは今回はメールアドレスの設定のみですが、今後情報が増えた際に個別に設定するのではなく、ここで設定できるように用意しています。
最後にアクションです。
commitで呼び出している内容は上記のミューテーションで定義したものです。
export const actions = { // ユーザー情報を取得します。 load: ({ commit }) => { var currentUser = UserAPI.getUser(); if(currentUser) { // ログイン済み commit('setIsLogin', true); commit('setEntity', currentUser); } else { // 未ログイン commit('setIsLogin', false); commit('clear'); } }, // 新規ユーザー登録を行います。 regist: ({ commit, dispatch }, payload) => { return UserAPI.regist(payload.mailAddress, payload.password) .then((res) =>{ commit('setIsLogin', true); dispatch('setEntity', res.user); }) .catch(function(error) { commit('setIsLogin', false); commit('setAuthError', error.message); commit('clear'); }); }, // 新規ユーザー登録を行います。 login: ({ commit, dispatch }, payload) => { return UserAPI.login(payload.mailAddress, payload.password) .then((res) =>{ commit('setIsLogin', true); dispatch('setEntity', res.user); }) .catch(function(error) { commit('setIsLogin', false); commit('setAuthError', error.message); commit('clear'); }); }, // 新規ユーザー登録を行います。 logout: ({ commit }) => { return UserAPI.logout() .then((res) =>{ commit('setIsLogin', false); commit('clear'); }) .catch(function(error) { commit('setAuthError', error.message); }); }, // 新規ユーザー登録を行います。 setEntity: ({ commit }, user) => { commit('setEntity', user); } }
以上でモジュールの完成です。
画面への組み込み
最後に画面を作成しましょう。
以下、auth.vueに追記していきます。
まずはログイン状態やエラーメッセージを画面で確認できるようにcomputedを用意します。
computed: { isLogin(){ return this.$store.state.user.isLogin; }, authError(){ return this.$store.state.user.authError; } },
これを使って画面の出し分けを行います。
新規ユーザー登録とログイン部分は未ログイン時のみ表示し、ログアウト部分はログイン時のみ表示します。
Firebaseからエラーが帰ってきた場合は、その内容が表示されるようにします。
また、ボタンに対してイベントを設定しました。
(追加部分にはコメントを入れました)
<!-- 新規登録に v-if="!isLogin" を追加 --> <section class="ex__box" v-if="!isLogin"> <h5>新規登録</h5> <p><input type="text" v-model="mailAddress" placeholder="メールアドレス"></p> <p><input type="password" v-model="password" placeholder="パスワード"></p> <!-- エラーメッセージ表示部分を追加 --> <p class="errMessage" v-if="authError">{{authError}}</p> <div class="links"> <!-- クリックイベントを追加 --> <a @click="regist()" class="button--green">新規登録</a> </div> </section> <!-- ログインに v-if="!isLogin" を追加 --> <section class="ex__box" v-if="!isLogin"> <h5>ログイン</h5> <p><input type="text" v-model="mailAddress" placeholder="メールアドレス"></p> <p><input type="password" v-model="password" placeholder="パスワード"></p> <!-- エラーメッセージ表示部分を追加 --> <p class="errMessage" v-if="authError">{{authError}}</p> <div class="links"> <!-- クリックイベントを追加 --> <a @click="login()" class="button--green">ログイン</a> </div> </section> <!-- ログアウトに v-if="isLogin" を追加 --> <section class="ex__box" v-if="isLogin"> <h5>ログイン中です</h5> <!-- ログイン中ユーザーのメールアドレスを表示 --> <p>メールアドレス:{{$store.state.user.emailAddress}}</p> <div class="links"> <!-- クリックイベントを追加 --> <a @click="logout()" class="button--grey">ログアウト</a> </div> </section>
ちなみに、この画面だと新規登録とログインで同じ変数を使っているので、どちらかに入力するともう一方にも反映されます。
本来であれば、画面の表示を片方(新規登録 or ログインどちらか一方しか表示されないよう)にするか、変数を分けるべきでしょう。
最後に、ユーザ新規登録・ログインなどを実行するためのメソッドを用意します。
methods: { init(): function() { this.password = ""; this.mailAddress = ""; }, regist: function () { this.$store.dispatch('user/regist', {mailAddress:this.mailAddress, password:this.password}); this.init(); }, login: function () { this.$store.dispatch('user/login', {mailAddress:this.mailAddress, password:this.password}); this.init(); }, logout : function() { this.$store.dispatch('user/logout'); } }
Vuexの詳細な説明はしませんが、今回作成したuserモジュールのregistアクションを使用するには以下のように書きます。
this.$store.dispatch('user/regist');
以上で、実装完了です。
実際の画面はこちら。
vueproducts-skylimitfuture.firebaseapp.com
随時更新中なので、ここで説明している内容から差異はあるかもしれませんが、基本的な実装は変わりません。
(現在はユーザー名の登録なども可能になっています)
以上です。