見出し画像

Nuxt.js firebaseでゲストログイン機能を実装する

本日はゲストログイン機能を実装していきたいと思います。

完成イメージ

画像9

といってもゲストログインのように見せかけて普通にログインさせる機能です。

サンプルアプリですのでこれが簡単かなと思います。


ボタンの作成

front/components/beforeLogin/gestLoginLink.vue
<template>
 <v-btn
   outlined
   dark
   color="success"
   class="ml-2 font-weight-bold"
   to="/posts/index"
 >
   {{ $t('pages.gest-login') }}
 </v-btn>
</template>
<script>
export default {
}
</script>

画像1

作成したボタンコンポーネントをヘッダーコンポーネントのなかに組み込みます。

画像2

組み込めました。

ここにゲストログインの機能を追加します。


機能の概要

通常ログインの仕様は

ログインボタン→ログイン画面→投稿一覧ページ

画像3

画像4

画像5


こんな感じで遷移します。

ログイン時のデータフローは

firebase.Authenticationにemailとパスワードを送信

Vuexにデータを送信

Vuexにデータ送信時にRailsと通信しデータをVuexに格納 

vuexのstateの値(user→ログインしたユーザー,loggedIn→ログインフラグこれがtrue)がそれぞれ変わりログインする

このデータフローをボタン一つですでに用意されたデータを使用してログインできるようにしていきます。


画像7

画像8

画像7


これでrails db:seedでゲストユーザーを用意できるようになりました。

すでにuserのデータを複数作ってしまっている場合はrails db:resetでデータを投入し直せます。

最終的なボタンコンポーネントのコード

<template>
 <v-btn
   outlined
   dark
   :loading="loading"
   color="success"
   class="ml-2 font-weight-bold"
   @click="loginGest"
 >
   {{ $t('pages.gest-login') }}
 </v-btn>
</template>
<script>
import { mapActions } from 'vuex'
import firebase from '~/plugins/firebase'
export default {
 data () {
   return {
     isValid: false,
     loading: false,
     user: { email: 'guest@example.com', password: 'guestpassword' }
   }
 },
 methods: {
   ...mapActions({
     login: 'auth/login',
     flashMessage: 'flash/flashMessage'
   }),
   loginGest () {
     this.loading = true
     firebase.auth().signInWithEmailAndPassword(this.user.email, this.user.password)
       .then((res) => {
         this.login(res.user)
         this.flashMessage({ message: 'ゲストログインしました', type: 'success', status: true })
         this.$router.push('/posts')
         this.loading = false
       })
       .catch((err) => {
         this.loading = false
         // eslint-disable-next-line no-console
         console.log(err)
         this.flashMessage({ message: 'メールアドレスまたはパスワードが正しくありません', type: 'error', status: true })
       })
   }
 }
}
</script>

コード+解説

このまま貼り付けてもエラーになるのでコピペする場合は上をコピペしてください

<template>
 <v-btn
   outlined ボタンの外枠をつけるオプション
   dark ダークテーマを適用する
   :loading="loading" data()のloadingとバインドしているloadingというデータがtrueになればボタンがくるくるする
   color="success" 色
   class="ml-2 font-weight-bold"
   @click="loginGest" ボタンをクリックした時にloginGestが発火する
 >
   {{ $t('pages.gest-login') }}
   <!-- myinjectで定義しているものこちらのサイトを詳しく読むといいかもしれません https://blog.cloud-acct.com/posts/u-logged-in-layouts-1-->
 </v-btn>
</template>
<script>
import { mapActions } from 'vuex' //mapActionsをインポート
import firebase from '~/plugins/firebase' //firebaseをインポート
export default {
 data () {
   return {
     loading: false,//ボタンのローディングをするかどうか判定しているデータ
     user: { email: 'guest@example.com', password: 'guestpassword' }//ログインの時に使うデータ
   }
 },
 methods: {
   ...mapActions({ //vuexの値をかえる
     login: 'auth/login',
     flashMessage: 'flash/flashMessage'
   }),
   loginGest () { //@clickされた時に発火するメソッド
     this.loading = true //ローディングフラグをtrueにするこれでくるくるする
     firebase.auth().signInWithEmailAndPassword(this.user.email, this.user.password)
       // firebase公式で紹介されていた書き方公式通りに書いただけです
       .then((res) => {
           // firebaseへの通信が成功した時
         this.login(res.user)
             // vuexのstateの値を変える
         this.flashMessage({ message: 'ゲストログインしました', type: 'success', status: true })
             // vuexのflashMessageの値を変える
         this.$router.push('/posts')
             // /postsへアクセス
         this.loading = false
             // ボタンくるくるを解除しておく
       })
       .catch((err) => {
           // エラーが出たときの処理
         this.loading = false
         // eslint-disable-next-line no-console
         console.log(err)
         this.flashMessage({ message: 'メールアドレスまたはパスワードが正しくありません', type: 'error', status: true })
       })
   }
 }
}
</script>


これで完成イメージと同じ様にゲストログインが可能になりました。


ただこのままだと名前が編集されたり、いたずらされる可能性もありますのでその対策もしていきます。

変えてほしくないものは

メールアドレス、パスワード、名前

その3つですのでそれを変えられないように設定していきます。


front側

ボタンを押させない

画像10

画像11

これを

guestId というdataを用意し

画像14

v-ifで条件分岐します。

普通のユーザー

画像13

ゲストユーザー

画像14

これで変更不可能になりました。

完璧に完全に防ぎたい場合は更に追加でバリデーション要素を付け加えます。

例えば、front側のデータ送信部分に

if (user.id != gestId ) { データ送信処理}

という感じで行っておけば更に強固になります。


更に付け加えたい場合はrailsのバリデーションにも条件式を付け加えるといいと思います。

それでは今日はこのへんで失礼します。

いいなと思ったら応援しよう!