Help us understand the problem. What is going on with this article?

Nuxt.jsとFirebaseでユーザー認証機能の実装( パスワード, Facebook,Google )

はじめに

フロントエンドエンジニアにとってユーザー認証のバックエンドを用意するのは手間になることが多いですよね。
そんなときに頼りになるのがFirebase。
Firebaseを導入すると簡単にユーザー認証機能が導入できるのでその手順をまとめました。

事前準備

以下を使用できる状態にしておきます。

  • vue.js
  • create-nuxt-app

Firebaseでプロジェクトの設定

下記Firebase Consoleにログインしてプロジェクトを作成します。
Firebase Console

スクリーンショット 2018-12-05 11.39.01.png

管理画面よりAuthを選択

section2.jpg

ログインプロバイダのメール/パスワードGoogleFacebookを有効化します。

スクリーンショット 2018-12-07 12.29.23.png

Facebookに関してはアプリケーションの設定が必要になります。
事前にFacebook for Developerよりアプリケーションを作成しておきアプリIDアプリシークレットを取得しておき登録します。

section3.jpg

さらにリダイレクトURLをFacebookアプリケーションに設定します。

section4.jpg

これで準備OK!

Nuxtアプリケーションを作成

今回はNuxtの雛形をそのまま使用します。
色々聞かれますが全てenterでOK、今回はパッケージマネージャーにyarnを選択します。

$ yarn create nuxt-app nuxt-login-app

Firebaseモジュールをインストールしておきます。

$ cd nuxt-login-app
$ yarn add firebase

こちらのコマンドでアプリを立ち上げ

$ yarn dev

アプリケーションが立ち上がりました。こちらで作成していきます。

スクリーンショット 2018-12-05 12.08.18.png

認証ページの作成

Google,Facebook,パスワードの順番にユーザー認証を実装していきます。

認証の準備

Firebase Consoleのこちらから認証情報を表示してAPI Key等の設定情報を表示します。

seciton1.jpg

configの内容をコピー

sample6.jpg

先ずはNuxtアプリケーションplugins内にfirebase.jsを作成してこちらの設定情報を利用します。

plugins/firebase.js
import firebase from 'firebase'

const config = {
  apiKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  authDomain: 'nuxt-login-app.firebaseapp.com',
  databaseURL: 'https://nuxt-login-app.firebaseio.com',
  projectId: 'nuxt-login-app',
  storageBucket: 'nuxt-login-app.appspot.com',
  messagingSenderId: '611183763562'
}

if (!firebase.apps.length) {
  firebase.initializeApp(config)
}

export default firebase

Google認証

まずはGoogle認証からpages/index.vueを書き換えます。
今回はリダイレクト方式を採用。
読み込み時にonAuthStateChangedでログイン状態をチェック。
ボタンクリックでgoogleLoginメソッドを実行。
それぞれFirebaseモジュールで用意されたオブジェクトを使用するので簡単に実装可能です。

Google ログイン ドキュメント

pages/index.vue
<template>
  <section class="container">
    <div v-if="isWaiting">
      <p>読み込み中</p>
    </div>
    <div v-else>
      <div v-if="!isLogin">
        <button @click="googleLogin">Googleでログイン</button>
      </div>
      <div v-else>
        <p>{{ user.email }}でログイン中</p>
        <button @click="logOut">ログアウト</button>
      </div>
    </div>
  </section>
</template>

<script>
import firebase from '@/plugins/firebase'

export default {
  asyncData () {
    return {
      isWaiting: true,
      isLogin: false,
      user: []
    }
  },
  mounted: function () {
    firebase.auth().onAuthStateChanged(user => {
      this.isWaiting = false
      if (user) {
        this.isLogin = true
        this.user = user
      } else {
        this.isLogin = false
        this.user = []
      }
    })
  },
  methods: {
    googleLogin () {
      const provider = new firebase.auth.GoogleAuthProvider()
      firebase.auth().signInWithRedirect(provider)
    },
    logOut () {
      firebase.auth().signOut()
    }
  }
}
</script>

Facebook認証

Facebookも基本的にはGoogleと同じです。
Facebook認証 ドキュメント

pages/index.vue
<template>
  <section class="container">
    <div v-if="isWaiting">
      <p>読み込み中</p>
    </div>
    <div v-else>
      <div v-if="!isLogin">
        <button @click="facebookLogin">Facebookでログイン</button>
      </div>
      <div v-else>
        <p>{{ user.email }}でログイン中</p>
        <button @click="logOut">ログアウト</button>
      </div>
    </div>
  </section>
</template>

<script>
import firebase from '@/plugins/firebase'

export default {
  asyncData () {
    return {
      isWaiting: true,
      isLogin: false,
      user: []
    }
  },
  mounted: function () {
    firebase.auth().onAuthStateChanged(user => {
      this.isWaiting = false
      if (user) {
        this.isLogin = true
        this.user = user
      } else {
        this.isLogin = false
        this.user = []
      };
    })
  },
  methods: {
    facebookLogin () {
      const provider = new firebase.auth.FacebookAuthProvider()
      firebase.auth().signInWithRedirect(provider)
    },
    logOut () {
      firebase.auth().signOut()
    }
  }
}
</script>

パスワード認証

パスワード認証はemailとpasswordを渡すだけです。
パスワードの文字数が6文字以上などの決まりがあるのでその辺りのバリデーションを適切に設定してください。
こちらは新規登録とログインで手順が違うのでregisterステータスで場合分けしています。
パスワード認証 ドキュメント

pages/index.vue
<template>
  <section class="container">
    <div v-if="isWaiting">
      <p>読み込み中</p>
    </div>
    <div v-else>
      <div v-if="!isLogin">
        <div>
          <p>
            <input
              v-model="email"
              type="text"
              placeholder="email"
            >
          </p>
          <p>
            <input
              v-model="password"
              type="password"
              placeholder="password"
            >
          </p>
          <p>
            <input
              id="checkbox"
              v-model="register"
              type="checkbox"
            >
            <label for="checkbox">新規登録</label>
          </p>
          <button @click="passwordLogin">{{ register ? '新規登録' : 'ログイン' }}</button>
          <p>{{ errorMessage }}</p>
        </div>
      </div>
      <div v-else>
        <p>{{ user.email }}でログイン中</p>
        <button @click="logOut">ログアウト</button>
      </div>
    </div>
  </section>
</template>

<script>
import firebase from '@/plugins/firebase'

export default {
  asyncData () {
    return {
      register: false,
      isWaiting: true,
      isLogin: false,
      user: [],
      email: '',
      password: '',
      errorMessage: ''
    }
  },
  mounted: function () {
    firebase.auth().onAuthStateChanged(user => {
      this.isWaiting = false
      this.errorMessage = ''
      if (user) {
        this.isLogin = true
        this.user = user
      } else {
        this.isLogin = false
        this.user = []
      };
    })
  },
  methods: {
    passwordLogin () {
      const email = this.email
      const password = this.password
      if (this.register) {
        firebase.auth().createUserWithEmailAndPassword(email, password).catch(function (error) {
          const errorMessage = error.message
          this.errorMessage = errorMessage
        }.bind(this))
      } else {
        firebase.auth().signInWithEmailAndPassword(email, password).catch(function (error) {
          const errorMessage = error.message
          this.errorMessage = errorMessage
        }.bind(this))
      }
    },
    logOut () {
      firebase.auth().signOut()
    }
  }
}
</script>

Firebase Consoleで各認証方法で登録したユーザーの追加が確認できました。
GUIで追加、編集等の管理ができるのが便利ですね。

sample5.jpg

最後に

Firebaseのログイン認証は以外にもデータベースやサーバー等フロントエンジニアにとって助かる機能がいくつもあるのでもっと活用していきたいですね。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away