Nuxt(SPA)上にFirebaseAuthで認証を追加する

はじめに

Nuxt.jsで作成したアプリケーションにFirebaseの認証を追加した時の備忘録。調べながら実装を進めたが、TypeScriptでの実装サンプルしか見つけられなかったので、JavaScript版を記録しておく。

環境

$ node -v
v11.10.0
$ npm -v
6.13.4
$ ./node_modules/nuxt/bin/nuxt.js -v
@nuxt/cli v2.11.0

Nuxt.jsアプリケーションの作成

$ npx create-nuxt-app <project-name>

詳細は、公式サイトを参考に。作成時にいくつか質問項目があるので、以下にまとめておきます。

$ npx create-nuxt-app firebase-auth-sample-js
create-nuxt-app v2.12.0
✨  Generating Nuxt.js project in firebase-auth-sample-js
? Project name firebase-auth-sample-js
? Project description My awe-inspiring Nuxt.js project
? Author name m1z0
? Choose the package manager Npm
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose test framework Jest
? Choose rendering mode Single Page App
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)

今回は、UIフレームワークにVuetify.js、サーバフレームワークはNone、レンダリングモードはSingle Page Appとしています。パッケージマネージャーはnpmを使用したので、yarn使いのかたは適宜読み替えてください。

Nuxt.jsアプリの起動

$ npm run dev

とりあえず、起動確認。http://localhost:3000/にアクセスして確認します。

ディレクトリ構成

├ components/
  ├ Logo.vue
  └ VuetifyLogo.vue
├ layouts/
  ├ default.vue
  └ error.vue
├ middleware/
 └ auth.js(追加)
├ pages/
  ├ index.vue
  └ login.vue(追加)
├ plugins/
  └ firebase.js(追加)
├ nuxt.config.js
├ firebase.config(追加)

* 大事なところのみ抜粋しています。

ログインページの作成

メールアドレスとパスワードを入力して、ログインするページを作成します。

<template>
  <v-form>
    <v-container>
      <v-text-field label="MailAddress" v-model="mail" ></v-text-field>
      <v-text-field label="Password" v-model="pass" type="password"></v-text-field>
      <v-btn color="primary" @click="login">ログイン</v-btn>
    </v-container>
  </v-form>
</template>

<script>
export default {
  data () {
    return {
      mail: '',
      pass: ''
    }
  },
  methods: {
    login () {
     alert('login done!')
    }
  }
}
</script>

そんなに難しいことはやっていないので、細かい説明は省きます。

Firebaseログイン実装

準備

とりあえず、SDKのインストールから始めましょう。

$ npm install -s firebase

SDKについて、詳しくは公式のリファレンスにて。

API Reference  |  Firebase JavaScript API reference
The Firebase JavaScript SDK implements the client-side libraries for applications using Firebase services.

呼び出し用pluginの作成

SDKのインストールが完了したら、どのコンポーネントからでも使用できるように、firebaseSDK呼び出し用プラグインをplugins配下に作っておきます。

ここで、apiキーなどの公開しない情報は、間違ってgitの公開レポジトリに上げちゃわないように、別ファイルに分けておきます。

import firebase from 'firebase/app'
import 'firebase/auth'
import config from '~/firebase.config'

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

export const auth = firebase.auth()
  export default {
    apiKey: "***********",
    authDomain: "***********",
    databaseURL: "***********",
    projectId: "***********",
    storageBucket: "***********",
    messagingSenderId: "***********",
    appId: "***********",
  }

firebase.configに書き込む情報の取得方法は、記載するのめんどくさいので公式のリファレンスを参考にしてください。

これで、使用したい場所でimport { auth } from 'plugins/firebase'すれば、認証関連の機能にアクセスできるようになりました。

ログイン処理の実装

先ほど作成したpages/login.vueに認証部分を追記していきます。

<template>
  <v-form>
    <v-container>
      <v-text-field label="MailAddress" v-model="mail" ></v-text-field>
      <v-text-field label="Password" v-model="pass" type="password"></v-text-field>
      <v-btn color="primary" @click="login">ログイン</v-btn>
    </v-container>
  </v-form>
</template>

<script>
// ここ追加①
import { auth } from '../plugins/firebase'

export default {
  data () {
    return {
      mail: '',
      pass: ''
    }
  },
  methods: {
    login () {
      // ここ追加②
      auth.signInWithEmailAndPassword(this.mail, this.pass)
        .then(user => this.$router.push('/'))
        .catch(e => alert(e.message))
    }
  }
}
</script>

ログイン処理自体は、// ここ追加②のたった3行で済みます。ログインに成功したらトップページへ遷移、失敗したらエラーメッセージをアラートします。

ログアウト処理の実装

ログアウト処理も実装しておきます。ログイン後はトップページ(index.vue)に遷移するので、そこにログアウトボタンを設けましょう。

<template>
  <v-btn v-if="isLogin">ログアウト</v-btn>
</template>

<script>
import { auth } from '../plugins/firebase'

export default {
  data () {
    return {
      isLogin: false
    }
  },
  async mounted () {
    // ログイン済みであれば、ログアウトボタンを表示する
    await auth.onAuthStateChanged((user) => this.isLogin = user ? true :false)
  },
  methods: {
    async logout() {
      await auth.signOut()
      this.$router.push('/login')
    }
  }
}
</script>

ログインしていなければログインページに飛ばす処理の実装

ログインしていなければ、ログアウトボタンが表示されないようにしましたが、そもそもアクセス時にログインしていなければ、ログインページに飛ばしてあげるのが親切ですよね。
この部分の実装をします。

import { auth } from '../plugins/firebase'

const middleware = ({ route, store, redirect }) => {
  auth.onAuthStateChanged((user) => {
    // ログインしていなければ、 /login へリダイレクトする
    if (!user && route.name !== 'login') redirect('/login')
  })
}

export default middleware

middlewareを有効にするために、もう一手間。nuxt.config.jsnoの最後に追記します。

...
  router: {
    middleware: ['auth']
  }
}

これで、middleware/auth.jsが有効化されます。

試してみる

まだユーザ登録機能を実装していないので、試すためにFirebase Consoleから手動でアカウントを追加しておきます。

Authenticationのログイン方法から、メール/パスワードでのログインを有効にして、

ユーザを追加します。

ここまでで作ったアプリに戻り、npm run devして、localhost:3000/にアクセス。

作成したアカウントでログインしてみます。

ログアウトボタンだけが設置されたページにたどり着けば、成功です。

参考

Nuxt(SPA)+Firebaseでログイン処理を実装する - Qiita
はじめに今回は、NuxtとFirebaseを使って認証処理を実装した時の記録を記事として残しておきます。※NuxtはTypescriptで実装するようにしています。作業環境OS: Windo…
タイトルとURLをコピーしました